Skip to content

Commit d81142e

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 408fa37 commit d81142e

File tree

2 files changed

+155
-163
lines changed

2 files changed

+155
-163
lines changed

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

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

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

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

0 commit comments

Comments
 (0)