问题
I have the following structure:
node_modules
- my_component
- font
- scss
- my_component.scss
src
- my_app.js
- my_app.scss
I'm trying to import the styles in my_component.scss
. This file contains @font-face
declarations with references to ../font/
. So something like:
// my_component.scss
@font-face {
font-family: 'Helvetica Neue';
font-weight: $weight-medium;
src: url('../font/font-file.eot');
}
In my_app.js
I'm requiring the SCSS file associated with it. So
// my_app.js
require('./my_app.scss');
//other app-specific code
I'm my_app.scss
, I'm importing my_component.scss
:
// my_app.scss
import 'my_component';
and the sassConfig
is set to resolve to node_modules/my_component/scss
so that the import works.
My loader config uses sass-loader
, resolve-url-loader
and css-loader
. Here's a snippet:
//loaders.js
loaders.push({
test: /\.scss$/,
loader: 'style!css?sourcemap!resolve-url!sass?sourceMap'
});
Here is what I observe:
- When I run
webpack-dev-server
, theurl
references resolve correctly - However, when I run
webpack
with the same conf file, I getModule not found: Error: Cannot resolve 'file' or 'directory' ../font/font-file.ttf
insrc/font/
Things I've tried:
- Using a
$font-path
variable to refer to../fonts
and setting it tonode_modules/my_components/font
- Checking the order of my loaders, updating my webpack version etc.
Update
My sassLoader
config previously had configuration for node-sass-import-once. When I removed it, my font urls started resolving again, however my generated CSS contains a ton of duplicate styles.
node-sass is repeatedly importing each @import
without doing any sort of deduping (I know it's not supposed to be able to do it by itself). But node-sass-import-once
which is meant for this sort of thing, breaks resolve-url-loader.
Here are my questions:
- Why does node-sass-import-once break the Webpack resolve-url-loader?
- Is there any way to dedupe the imports Webpack and get generated CSS free of style duplication?
回答1:
Without seeing your Webpack config I can only hazard a guess but it looks like you are trying to import a CSS file from node_modules
.
When you want to import CSS from node_modules
you may have to use the ~
. As sokra himself says in this issue:
css @import is relative to the current directory. For resolving "like a module" you can prefix ~.
So maybe something like @import `~module/my_component.scss`;
might do the trick.
Resolving imports this way also solved an issue I had where x.css
was required by x.js
and imported by y.css
when x.css
imported some sass variable config. Using resolve.alias in Webpack config I could simply do something like:
// webpack.config.js
resolve: {
alias: {
styles: 'src/styles/'
}
}
And then use the tilde to import:
// y.css
@import `~styles/x.scss
If this works then you needn't remove thenode-sass-import-once
and everything should resolve correctly.
来源:https://stackoverflow.com/questions/36926521/webpack-sass-loader-cannot-dedupe-common-scss-imports