javascript - scss 中的 webpack 5 图像/字体无法正确编译
问题描述
我的问题是;我的 .scss 文件中的图像和字体被重命名为哈希,并且 scss 文件中的 url 路径正在更改。我的 .scss 文件被导入到文件最顶部的 app.js 中,例如:
import '../scss/app.scss';
我的 .scss 文件中的示例:
@font-face {
font-family: 'FTBase';
src: url("../fonts/FTBase-Book.woff2") format("woff2"),
url("../fonts/FTBase-Book.woff") format("woff");
font-weight: 350;
font-style: normal;
font-display: swap
}
.event--1 {
background: var(--salmon) url("../images/leading-women.jpg") no-repeat center;
background-size: contain;
}
我运行 dev/build/production 后的输出是:
@font-face {
font-family: "FTBase";
src: url(../51ebe4030489fa0868f9.woff2) format("woff2"), url(../be034b081210fbdf38a2.woff) format("woff");
font-weight: 350;
font-style: normal;
font-display: swap;
}
.event--2 {
background: var(--salmon) url(../485639d38ea610d7bba2.jpg) no-repeat center;
background-size: cover;
}
并将图像/字体输出到/dist。
这是我的 webpack 文件:webpack.config.js:
const templateFiles = fs.readdirSync(environment.paths.source)
.filter((file) => path.extname(file).toLowerCase() === '.html');
const htmlPluginEntries = templateFiles.map((template) => new HTMLWebpackPlugin({
inject: 'body',
hash: false,
minify: false,
filename: template,
template: path.resolve(environment.paths.source, template),
favicon: path.resolve(environment.paths.source, 'images', 'favicon.ico'),
}));
module.exports = {
entry: {
app: path.resolve(environment.paths.source, 'js', 'app.js'),
},
output: {
filename: 'js/[name].js',
path: environment.paths.output,
},
module: {
rules: [{
test: /\.((c|sa|sc)ss)$/i,
use: [{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../',
}
}, {
loader: 'css-loader',
}, {
loader: 'sass-loader',
}, {
loader: 'postcss-loader',
}],
},
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.(png|gif|jpe?g|svg|jpg)$/i,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/',
},
}, ],
},
{
test: /\.(eot|ttf|woff|woff2)$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/',
},
}, ],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].min.css',
}),
new ImageminWebpWebpackPlugin({
config: [{
test: /\.(jpe?g|png)/,
options: {
quality: 76,
}
}],
overrideExtension: true,
detailedLogs: false,
silent: false,
strict: true,
}),
new CleanWebpackPlugin({
verbose: true,
cleanOnceBeforeBuildPatterns: ['**/*', '!stats.json'],
}),
new CopyWebpackPlugin({
patterns: [{
from: path.resolve(environment.paths.source, 'images'),
to: path.resolve(environment.paths.output, 'images'),
toType: 'dir',
globOptions: {
ignore: ['*.DS_Store', 'Thumbs.db'],
},
}, ],
}),
].concat(htmlPluginEntries),
target: 'web',
};
webpack.dev.config.js:
const webpackConfiguration = require('../webpack.config');
const environment = require('./environment');
module.exports = merge(webpackConfiguration, {
mode: 'development',
/* Manage source maps generation process */
devtool: 'eval-source-map',
/* Development Server Configuration */
devServer: {
contentBase: environment.paths.output,
watchContentBase: true,
publicPath: '/',
open: true,
historyApiFallback: true,
compress: true,
overlay: true,
hot: false,
watchOptions: {
poll: 300,
},
...environment.server,
},
/* File watcher options */
watchOptions: {
aggregateTimeout: 300,
poll: 300,
ignored: /node_modules/,
},
/* Additional plugins configuration */
plugins: [],
});
webpack.prod.config.js:
const webpackConfiguration = require('../webpack.config');
module.exports = merge(webpackConfiguration, {
mode: 'production',
/* Manage source maps generation process. Refer to https://webpack.js.org/configuration/devtool/#production */
devtool: false,
/* Optimization configuration */
optimization: {
splitChunks: {
chunks: 'all',
name: 'vendor',
},
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
}),
new CssMinimizerPlugin(),
],
},
/* Performance treshold configuration values */
performance: {
maxEntrypointSize: 512000,
maxAssetSize: 512000,
},
/* Additional plugins configuration */
plugins: [],
});
在我的 webpack.config.js 文件中,我尝试在 css-loader 和 sass-loader 上将 sourceMaps 设置为 true,更改 publicPath 以及我在其他论坛上尝试过的其他一些事情,但没有成功。
解决方案
所以我想通了,我必须从图像和字体中删除文件加载器。我将其替换为:
{
test: /\.(png|jpg|gif|svg)$/,
type: 'asset/resource',
}, {
test: /.(ttf|otf|eot|woff(2)?)(\?[a-z0-9]+)?$/,
type: 'asset/resource',
},
然后我不得不将输出编辑为:
output: {
filename: 'js/[name].js',
path: environment.paths.output,
assetModuleFilename: 'assets/[name][ext]',
},
所以现在当我运行 dev/build/production 时,它会抓取 scss 文件中的所有资产,保持它们相同的名称,并创建一个名为“assets”的文件夹,该文件夹位于“/dist/assets”,它会自动更改 url在 scss 文件中到 '../assets/image.jpg'
推荐阅读
- javascript - 如何通过索引从多个数组中获取一个值?
- php - laravel - 将数据从第一页传递到第三页
- latex - 在moderncv中将最后页码设置为固定值
- ios - 尝试在类 ViewController 中使用 UIImage 数组来显示彩色矩形时构建错误
- arrays - 我正在阅读“The C Programming Language”(第 2 版),但我不理解一个概念:
- unit-testing - 单元测试 TelemetryProcessor 和 TelemetryInitializer(Application Insights)?
- c++ - 为什么使用引用数组的 auto 会被推导出为指针?
- computer-vision - 劣质日期戳上的字符识别
- typescript - 在 Typescript 中重命名键的函数因“可以用不同的子类型实例化”错误而失败?
- html - Bootstrap5 ms-auto 在行/列元素中未按预期工作