可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm using webpack to build my react components and I'm trying to use the extract-text-webpack-plugin
to separate my css from my generated js file. However, when I attempt to build the component I get the following error: Module build failed: ReferenceError: window is not defined
.
My webpack.config.js file looks like this:
var webpack = require('webpack'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: { MainComponent: './src/main.js' }, output: { libraryTarget: 'var', library: 'MainComponent', path: './build', filename: '[name].js' }, module: { loaders: [{ test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader!css-loader') }] }, plugins: [ new ExtractTextPlugin('styles.css') ] }
回答1:
You may want to use style-loader
as a before
argument in extract
function.
Here's the native implementation:
ExtractTextPlugin.extract = function(before, loader, options) { if(typeof loader === "string") { return [ ExtractTextPlugin.loader(mergeOptions({omit: before.split("!").length, extract: true, remove: true}, options)), before, loader ].join("!"); } else { options = loader; loader = before; return [ ExtractTextPlugin.loader(mergeOptions({remove: true}, options)), loader ].join("!"); } };
So basicaly what you need to do is:
{ test: /\.sass$/, exclude: /node_modules/, loader: ExtractTextPlugin.extract('style-loader', 'css!sass?indentedSyntax=true&sourceMap=true') },
if you for example use sass
.
回答2:
Didn't see an explanation of the cause so I have posted this answer here.
From https://github.com/webpack/extract-text-webpack-plugin#api
ExtractTextPlugin.extract([notExtractLoader], loader, [options])
Creates an extracting loader from an existing loader.
notExtractLoader
(optional) the loader(s) that should be used when the css is not extracted (i.e. in an > additional chunk when allChunks: false)
loader
the loader(s) that should be used for converting the resource to a css exporting module.
options
publicPath
override the publicPath setting for this loader.
The #extract
method should receive a loader that outputs css
. What was happening was that it was receiving a style-loader
which outputs javascript code, which is intended to be injected into a webpage. This code would try to access window
.
You should not pass a loader string with style
to #extract
. However...if you set allChunks=false
, then it will not build CSS files for non-initial chunks. Therefore it needs to know what loader to use to inject into the page.
Tip: Webpack is a tool that really needs to be understood in-depth or you can run into lots of strange issues.
回答3:
Webpack 2
If you're using Webpack 2, this variation works:
rules: [{ test: /\.css$/, exclude: '/node_modules/', use: ExtractTextPlugin.extract({ fallback: [{ loader: 'style-loader', }], use: [{ loader: 'css-loader', options: { modules: true, localIdentName: '[name]__[local]--[hash:base64:5]', }, }, { loader: 'postcss-loader', }], }), }]
The new extract method no longer takes three arguments, and is listed as a breaking change when moving from V1 to V2.
https://webpack.js.org/guides/migrating/#extracttextwebpackplugin-breaking-change
回答4:
I figured out the solution to my problem:
Instead of piping the loaders into one another (ExtractTextPlugin.extract('style-loader!css-loader')
), you have to pass in the each loader as a separate parameter: ExtractTextWebpackPlugin.extract('style-loader', 'css-loader')