Mag*_*nus 12 javascript css webpack webpack-style-loader css-loader
有一些关于style-loaderand 的SO 帖子css-loader,但尽管如此,我还是无法找到解决我的问题的方法。
简而言之,当我@import css在其他css文件中归档时,导入的css包含url()具有相对路径的 s 时,路径解析不正确。
基本上,错误消息表明 Webpack 最终认为url()导入的 css 中的路径是相对于src(主入口点),而不是相对于css它导入的文件:
// css-one.scss
@import "./assets/open-iconic-master/font/css/open-iconic-bootstrap.css";
// open-iconic-bootstrap.css
@font-face {
src: url('../fonts/open-iconic.eot');
}
Run Code Online (Sandbox Code Playgroud)
错误:
./src/main.scss 中的错误 (./node_modules/css-loader??ref--5-1!./node_modules/postcss-loader/src??ref--5-2!./node_modules/sass- loader/lib/loader.js??ref--5-3!./src/main.scss)
模块未找到:错误:无法解析'../fonts/open-iconic.eot'在 'C:\用户\ ... \ src'中 @ ./src/main.scss (./node_modules/css- loader??ref--5-1!./node_modules/postcss-loader/src??ref--5-2!./node_modules/sass-loader/lib/loader.js??ref--5-3! ./src/main.scss) 7:106-141 7:172-207 @ ./src/main.scss @ ./src/index.js
我试过的:
convertToAbsoluteUrls在 style-loader 中使用该标志我的 Webpack 配置文件(加载程序在底部):
// css-one.scss
@import "./assets/open-iconic-master/font/css/open-iconic-bootstrap.css";
// open-iconic-bootstrap.css
@font-face {
src: url('../fonts/open-iconic.eot');
}
Run Code Online (Sandbox Code Playgroud)
小智 12
我花了大约 5 天的时间来理解这个 webpack 混乱是如何工作的。老实说,我可以说这是我真的不明白为什么它们是目前“事实上的”工具之一。我无法理解仅仅让配置文件正常工作有多困难,在 gulp 中我花了 1 小时来做同样的事情。
我的问题是所有 url() 规则(包括字体和图像)都由 css-loader 作为 [object Module] 加载,并且它们由 file-loader 导出但从未加载,所以如果我添加 ?url=false 到css-loader 它从不复制文件并导出它们。我不得不说这完全是一个 PITA,但我让它工作了,我希望它适用于世界上的其他人,这是用 webpack 4 制作的。
const webpack = require("webpack");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
entry: "./src/index.js",
mode: "development",
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
loader: "babel-loader",
options: { presets: ["@babel/env"] }
},
{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
optipng: {
enabled: false,
},
pngquant: {
quality: [0.65, 0.90],
speed: 4
},
gifsicle: {
interlaced: false,
},
webp: {
quality: 75
},
}
},
{
loader: 'file-loader',
options:{
name: '[name].[ext]',
outputPath: 'images/',
publicPath: 'images/'
}
},
'url-loader?limit=100000'
],
},
{
test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
]
},
{
test: /\.s[ac]ss$/i,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader?url=false'},
{ loader: 'sass-loader', options: { sourceMap: true } }
],
},
]
},
resolve: { extensions: ["*", ".js", ".jsx"] },
output: {
path: path.resolve(__dirname, "dist/"),
publicPath: "",
filename: "bundle.js"
},
devServer: {
contentBase: path.join(__dirname, "dist/"),
port: 3000,
publicPath: "http://localhost:3000/dist/",
hotOnly: true
},
plugins: [ new MiniCssExtractPlugin(),
new CopyPlugin([{ from: 'src/images/', to: 'images/' }]),
new CopyPlugin([{ from: 'src/fonts/', to: 'fonts/' }]),
new ImageminPlugin({ test: /\.(jpe?g|png|gif|svg)$/i }),
new HtmlWebpackPlugin({
hash: true,
template: './src/index.html',
filename: './index.html' //relative to root of the application
}),
]
};
Run Code Online (Sandbox Code Playgroud)
Mag*_*nus 10
我能够自己解决问题。如果将来可以帮助其他人,请在下面找到解决方案。
postcss-loader与postcss-import开发插件,并且css-loader,关闭/删除postcss-import插件。您不需要多个解决@import规则的工具。如果加载程序的顺序正确,这并不是真正的问题,但您不妨将其删除。由于 Sass/libsass 不提供 url 重写,因此所有链接的资产都必须与输出相关。
如果您只是生成 CSS 而不将其传递给 css-loader,则它必须与您的 Web 根目录相关。
如果您将生成的 CSS 传递给 css-loader,则所有 url 都必须相对于入口文件(例如 main.scss)。
您更有可能被第二个问题打扰。很自然地期望相对引用针对指定它们的 .scss 文件(如在常规 .css 文件中)进行解析。幸运的是,这个问题有两种解决方案:
使用resolve-url-loader 添加丢失的url 重写。将它放在 loader 链中的 sass-loader 之前。
库作者通常提供一个变量来修改资产路径。例如 bootstrap-sass 有一个 $icon-font-path。查看这个工作引导程序示例。
我决定遵循第二点,并在Webpack配置中添加resolve-url-loader上面sass-loader的内容。它现在按预期工作。
我的最终 Webpack 配置(目前)如下所示:
{
test: /\.s?[ac]ss$/,
exclude: /node_modules/,
use: [
isProduction
? MiniCssExtractPlugin.loader
: {
// creates style nodes from JS strings
loader: 'style-loader',
options: {
sourceMap: true,
// convertToAbsoluteUrls: true
}
},
{
// CSS to CommonJS (resolves CSS imports into exported CSS strings)
loader: 'css-loader',
options: {
sourceMap: true,
importLoaders: 2
// url: false,
// import: false
}
},
{
loader: 'postcss-loader',
options: {
config: {
ctx: {
cssnext: {},
cssnano: {},
autoprefixer: {}
}
},
sourceMap: true
}
},
{
loader: 'resolve-url-loader',
options: {
attempts: 1,
sourceMap: true
}
},
{
// compiles Sass to CSS
loader: 'sass-loader',
options: { sourceMap: true }
}
]
},
Run Code Online (Sandbox Code Playgroud)
旁注
请记住在 中包含以下副作用package.json,因此在生产模式下发生的摇树不会删除提取的 css
"sideEffects": [ " .css", " .scss"],
url()顺便说一句,您可以关闭规则处理。我不知道为什么这是默认行为。
{
loader: 'css-loader',
options: {
...
url: false,
}
},
Run Code Online (Sandbox Code Playgroud)