Skip to content

Commit e0c2729

Browse files
FurizaaJohnNilsson
authored andcommitted
Use Rule.oneOf to resolve correct loader (#2747)
* Use oneOf to resolve correct loader * Add html and json fallthrough again * Use oneOf to resolve correct loader in dev * Document file-loaders `js` exclusion * Remove `jsx` from exclusion in prod config
1 parent 63e8924 commit e0c2729

File tree

2 files changed

+155
-161
lines changed

2 files changed

+155
-161
lines changed

packages/react-scripts/config/webpack.config.dev.js

+67-70
Original file line numberDiff line numberDiff line change
@@ -150,88 +150,85 @@ module.exports = {
150150
enforce: 'pre',
151151
include: paths.appSrc,
152152
},
153-
// ** ADDING/UPDATING LOADERS **
154-
// The "file" loader handles all assets unless explicitly excluded.
155-
// The `exclude` list *must* be updated with every change to loader extensions.
156-
// When adding a new loader, you must add its `test`
157-
// as a new entry in the `exclude` list for "file" loader.
158-
159-
// "file" loader makes sure those assets get served by WebpackDevServer.
160-
// When you `import` an asset, you get its (virtual) filename.
161-
// In production, they would get copied to the `build` folder.
162-
{
163-
exclude: [
164-
/\.html$/,
165-
/\.(js|jsx)$/,
166-
/\.(ts|tsx)$/,
167-
/\.css$/,
168-
/\.json$/,
169-
/\.bmp$/,
170-
/\.gif$/,
171-
/\.jpe?g$/,
172-
/\.png$/,
173-
],
174-
loader: require.resolve('file-loader'),
175-
options: {
176-
name: 'static/media/[name].[hash:8].[ext]',
177-
},
178-
},
179-
// "url" loader works like "file" loader except that it embeds assets
180-
// smaller than specified limit in bytes as data URLs to avoid requests.
181-
// A missing `test` is equivalent to a match.
182-
{
183-
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
184-
loader: require.resolve('url-loader'),
185-
options: {
186-
limit: 10000,
187-
name: 'static/media/[name].[hash:8].[ext]',
188-
},
189-
},
190-
// Compile .tsx?
191-
{
192-
test: /\.(ts|tsx)$/,
193-
include: paths.appSrc,
194-
loader: require.resolve('ts-loader'),
195-
},
196-
// "postcss" loader applies autoprefixer to our CSS.
197-
// "css" loader resolves paths in CSS and adds assets as dependencies.
198-
// "style" loader turns CSS into JS modules that inject <style> tags.
199-
// In production, we use a plugin to extract that CSS to a file, but
200-
// in development "style" loader enables hot editing of CSS.
201153
{
202-
test: /\.css$/,
203-
use: [
204-
require.resolve('style-loader'),
154+
// "oneOf" will traverse all following loaders until one will
155+
// match the requirements. When no loader matches it will fall
156+
// back to the "file" loader at the end of the loader list.
157+
oneOf: [
158+
// "url" loader works like "file" loader except that it embeds assets
159+
// smaller than specified limit in bytes as data URLs to avoid requests.
160+
// A missing `test` is equivalent to a match.
205161
{
206-
loader: require.resolve('css-loader'),
162+
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
163+
loader: require.resolve('url-loader'),
207164
options: {
208-
importLoaders: 1,
165+
limit: 10000,
166+
name: 'static/media/[name].[hash:8].[ext]',
209167
},
210168
},
169+
// Compile .tsx?
211170
{
212-
loader: require.resolve('postcss-loader'),
213-
options: {
214-
// Necessary for external CSS imports to work
215-
// https://github.com/facebookincubator/create-react-app/issues/2677
216-
ident: 'postcss',
217-
plugins: () => [
218-
require('postcss-flexbugs-fixes'),
219-
autoprefixer({
220-
browsers: [
221-
'>1%',
222-
'last 4 versions',
223-
'Firefox ESR',
224-
'not ie < 9', // React doesn't support IE8 anyway
171+
test: /\.(ts|tsx)$/,
172+
include: paths.appSrc,
173+
loader: require.resolve('ts-loader'),
174+
},
175+
// "postcss" loader applies autoprefixer to our CSS.
176+
// "css" loader resolves paths in CSS and adds assets as dependencies.
177+
// "style" loader turns CSS into JS modules that inject <style> tags.
178+
// In production, we use a plugin to extract that CSS to a file, but
179+
// in development "style" loader enables hot editing of CSS.
180+
{
181+
test: /\.css$/,
182+
use: [
183+
require.resolve('style-loader'),
184+
{
185+
loader: require.resolve('css-loader'),
186+
options: {
187+
importLoaders: 1,
188+
},
189+
},
190+
{
191+
loader: require.resolve('postcss-loader'),
192+
options: {
193+
// Necessary for external CSS imports to work
194+
// https://github.com/facebookincubator/create-react-app/issues/2677
195+
ident: 'postcss',
196+
plugins: () => [
197+
require('postcss-flexbugs-fixes'),
198+
autoprefixer({
199+
browsers: [
200+
'>1%',
201+
'last 4 versions',
202+
'Firefox ESR',
203+
'not ie < 9', // React doesn't support IE8 anyway
204+
],
205+
flexbox: 'no-2009',
206+
}),
225207
],
226-
flexbox: 'no-2009',
227-
}),
228-
],
208+
},
209+
},
210+
],
211+
},
212+
// "file" loader makes sure those assets get served by WebpackDevServer.
213+
// When you `import` an asset, you get its (virtual) filename.
214+
// In production, they would get copied to the `build` folder.
215+
// This loader don't uses a "test" so it will catch all modules
216+
// that fall through the other loaders.
217+
{
218+
// Exclude `js` files to keep "css" loader working as it injects
219+
// it's runtime that would otherwise processed through "file" loader.
220+
// Also exclude `html` and `json` extensions so they get processed
221+
// by webpacks internal loaders.
222+
exclude: [/\.js$/, /\.html$/, /\.json$/],
223+
loader: require.resolve('file-loader'),
224+
options: {
225+
name: 'static/media/[name].[hash:8].[ext]',
229226
},
230227
},
231228
],
232229
},
233230
// ** STOP ** Are you adding a new loader?
234-
// Remember to add the new extension(s) to the "file" loader exclusion list.
231+
// Make sure to add the new loader(s) before the "file" loader.
235232
],
236233
},
237234
plugins: [

packages/react-scripts/config/webpack.config.prod.js

+88-91
Original file line numberDiff line numberDiff line change
@@ -150,103 +150,100 @@ module.exports = {
150150
enforce: 'pre',
151151
include: paths.appSrc,
152152
},
153-
// ** ADDING/UPDATING LOADERS **
154-
// The "file" loader handles all assets unless explicitly excluded.
155-
// The `exclude` list *must* be updated with every change to loader extensions.
156-
// When adding a new loader, you must add its `test`
157-
// as a new entry in the `exclude` list in the "file" loader.
158-
159-
// "file" loader makes sure those assets end up in the `build` folder.
160-
// When you `import` an asset, you get its filename.
161-
{
162-
exclude: [
163-
/\.html$/,
164-
/\.(js|jsx)$/,
165-
/\.(ts|tsx)$/,
166-
/\.css$/,
167-
/\.json$/,
168-
/\.bmp$/,
169-
/\.gif$/,
170-
/\.jpe?g$/,
171-
/\.png$/,
172-
],
173-
loader: require.resolve('file-loader'),
174-
options: {
175-
name: 'static/media/[name].[hash:8].[ext]',
176-
},
177-
},
178-
// "url" loader works just like "file" loader but it also embeds
179-
// assets smaller than specified size as data URLs to avoid requests.
180-
{
181-
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
182-
loader: require.resolve('url-loader'),
183-
options: {
184-
limit: 10000,
185-
name: 'static/media/[name].[hash:8].[ext]',
186-
},
187-
},
188-
// Compile .tsx?
189-
{
190-
test: /\.(ts|tsx)$/,
191-
include: paths.appSrc,
192-
loader: require.resolve('ts-loader'),
193-
},
194-
// The notation here is somewhat confusing.
195-
// "postcss" loader applies autoprefixer to our CSS.
196-
// "css" loader resolves paths in CSS and adds assets as dependencies.
197-
// "style" loader normally turns CSS into JS modules injecting <style>,
198-
// but unlike in development configuration, we do something different.
199-
// `ExtractTextPlugin` first applies the "postcss" and "css" loaders
200-
// (second argument), then grabs the result CSS and puts it into a
201-
// separate file in our build process. This way we actually ship
202-
// a single CSS file in production instead of JS code injecting <style>
203-
// tags. If you use code splitting, however, any async bundles will still
204-
// use the "style" loader inside the async code so CSS from them won't be
205-
// in the main CSS file.
206153
{
207-
test: /\.css$/,
208-
loader: ExtractTextPlugin.extract(
209-
Object.assign(
210-
{
211-
fallback: require.resolve('style-loader'),
212-
use: [
213-
{
214-
loader: require.resolve('css-loader'),
215-
options: {
216-
importLoaders: 1,
217-
minimize: true,
218-
sourceMap: true,
219-
},
220-
},
154+
// "oneOf" will traverse all following loaders until one will
155+
// match the requirements. When no loader matches it will fall
156+
// back to the "file" loader at the end of the loader list.
157+
oneOf: [
158+
// "url" loader works just like "file" loader but it also embeds
159+
// assets smaller than specified size as data URLs to avoid requests.
160+
{
161+
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
162+
loader: require.resolve('url-loader'),
163+
options: {
164+
limit: 10000,
165+
name: 'static/media/[name].[hash:8].[ext]',
166+
},
167+
},
168+
//Compile .tsx?
169+
{
170+
test: /\.(ts|tsx)$/,
171+
include: paths.appSrc,
172+
loader: require.resolve('ts-loader')
173+
},
174+
// The notation here is somewhat confusing.
175+
// "postcss" loader applies autoprefixer to our CSS.
176+
// "css" loader resolves paths in CSS and adds assets as dependencies.
177+
// "style" loader normally turns CSS into JS modules injecting <style>,
178+
// but unlike in development configuration, we do something different.
179+
// `ExtractTextPlugin` first applies the "postcss" and "css" loaders
180+
// (second argument), then grabs the result CSS and puts it into a
181+
// separate file in our build process. This way we actually ship
182+
// a single CSS file in production instead of JS code injecting <style>
183+
// tags. If you use code splitting, however, any async bundles will still
184+
// use the "style" loader inside the async code so CSS from them won't be
185+
// in the main CSS file.
186+
{
187+
test: /\.css$/,
188+
loader: ExtractTextPlugin.extract(
189+
Object.assign(
221190
{
222-
loader: require.resolve('postcss-loader'),
223-
options: {
224-
// Necessary for external CSS imports to work
225-
// https://github.com/facebookincubator/create-react-app/issues/2677
226-
ident: 'postcss',
227-
plugins: () => [
228-
require('postcss-flexbugs-fixes'),
229-
autoprefixer({
230-
browsers: [
231-
'>1%',
232-
'last 4 versions',
233-
'Firefox ESR',
234-
'not ie < 9', // React doesn't support IE8 anyway
191+
fallback: require.resolve('style-loader'),
192+
use: [
193+
{
194+
loader: require.resolve('css-loader'),
195+
options: {
196+
importLoaders: 1,
197+
minimize: true,
198+
sourceMap: true,
199+
},
200+
},
201+
{
202+
loader: require.resolve('postcss-loader'),
203+
options: {
204+
// Necessary for external CSS imports to work
205+
// https://github.com/facebookincubator/create-react-app/issues/2677
206+
ident: 'postcss',
207+
plugins: () => [
208+
require('postcss-flexbugs-fixes'),
209+
autoprefixer({
210+
browsers: [
211+
'>1%',
212+
'last 4 versions',
213+
'Firefox ESR',
214+
'not ie < 9', // React doesn't support IE8 anyway
215+
],
216+
flexbox: 'no-2009',
217+
}),
235218
],
236-
flexbox: 'no-2009',
237-
}),
238-
],
239-
},
219+
},
220+
},
221+
],
240222
},
241-
],
223+
extractTextPluginOptions
224+
)
225+
),
226+
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
227+
},
228+
// "file" loader makes sure assets end up in the `build` folder.
229+
// When you `import` an asset, you get its filename.
230+
// This loader don't uses a "test" so it will catch all modules
231+
// that fall through the other loaders.
232+
{
233+
loader: require.resolve('file-loader'),
234+
// Exclude `js` files to keep "css" loader working as it injects
235+
// it's runtime that would otherwise processed through "file" loader.
236+
// Also exclude `html` and `json` extensions so they get processed
237+
// by webpacks internal loaders.
238+
exclude: [/\.js$/, /\.html$/, /\.json$/],
239+
options: {
240+
name: 'static/media/[name].[hash:8].[ext]',
242241
},
243-
extractTextPluginOptions
244-
)
245-
),
246-
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
242+
},
243+
// ** STOP ** Are you adding a new loader?
244+
// Make sure to add the new loader(s) before the "file" loader.
245+
],
247246
},
248-
// ** STOP ** Are you adding a new loader?
249-
// Remember to add the new extension(s) to the "file" loader exclusion list.
250247
],
251248
},
252249
plugins: [

0 commit comments

Comments
 (0)