javascript - Webpack:如何在 .css 中重写 URL
问题描述
连续 3 天我在设置 Webpack 以进行暂存时遇到了麻烦。目标是在最终的 .css 文件(frontend.css)中重写资产的 url,如下所示:
假设在 .scss 文件中我有:
background: url('/assets/image.png')
(这适用于开发和产品)
在最终输出的 .css 文件中,我希望它是:
background: url('https://stage.domain.com/staging/project-name/assets/image.png')
我有脚本npm run stage
,构建 js。和 .css 仅用于暂存目的。它使用两个文件在根目录上创建阶段目录frontened-bundle.js and frontend.css.
(参见“文件结构”屏幕截图的底部)。
我试图用带有根参数的resolve-url-loader重写url,但我无法让它工作。publicPath 也被忽略。
我不确定我做错了什么。请指出我正确的方向。
文件结构:
webpack.stage.js:
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const public_path = 'https://stage.domain.com/staging/project-name/'
module.exports = {
context: __dirname,
entry: {
frontend: [
'./src/js/index.js',
'./src/scss/main.scss'
],
// customizer: './src/customizer.js'
},
resolve: {
extensions: ['.ts', '.js', '.jsx', '.scss', '...',],
},
output: {
path: path.resolve(__dirname, 'stage'),
publicPath: public_path,
filename: '[name]-bundle.js'
},
mode: 'production',
// devtool: 'cheap-eval-source-map',
module: {
rules: [
{
enforce: 'pre',
exclude: /node_modules/,
test: /\.jsx$/,
loader: 'eslint-loader'
},
{
test: /\.jsx?$/,
loader: 'babel-loader'
},
{
test: /\.s?css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: public_path,
sourceMap: true
}
},
{
loader: 'css-loader',
options: {
url: false,
sourceMap: true
}
},
{
loader: 'resolve-url-loader',
options: {
// root: path.join(__dirname, './'), // returns url("../../assets/assets/fonts/NewYork.woff2")
// root: '/', // returns url('../../../../../../assets/fonts/NewYork.woff2')
// root: './', // returns url('../../assets/fonts/NewYork.woff2')
attempts: 1,
debug: true,
sourceMap: true,
publicPath: public_path,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
},
]
},
{
test: /\.(ttf|woff|woff2|eot|jpe?g|png|svg|gif)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
// outputPath: '../',
publicPath: publicPath,
},
},
'img-loader',
'url-loader',
]
}
]
},
plugins: [
// new StyleLintPlugin(),
new MiniCssExtractPlugin({
filename: '[name].css'
}),
],
optimization: {
// minimizer: [new UglifyJsPlugin(), new OptimizeCssAssetsPlugin()]
}
};
包.json
{
"name": "project_name",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --mode=production",
"dev": "webpack --watch",
"stage": "npm run clean && webpack --config webpack.stage.js -p --progress --profile",
"clean": "rm -rf stage"
},
"repository": {
"type": "git",
"url": ""
},
"keywords": [
"webpack"
],
"author": "",
"license": "ISC",
"bugs": {
"url": ""
},
"homepage": "",
"devDependencies": {
"@babel/cli": "^7.14.5",
"@babel/core": "^7.6.2",
"@babel/preset-env": "^7.6.2",
"autoprefixer": "^9.6.4",
"babel-eslint": "^10.0.3",
"babel-loader": "^8.0.6",
"browser-sync": "^2.27.4",
"browser-sync-webpack-plugin": "^2.2.2",
"css-loader": "^3.2.0",
"css-mqpacker": "^7.0.0",
"eslint": "^6.5.1",
"eslint-config-prettier": "^6.4.0",
"eslint-config-wordpress": "^2.0.0",
"eslint-loader": "^3.0.2",
"eslint-plugin-prettier": "^3.1.1",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^4.2.0",
"img-loader": "^3.0.1",
"mini-css-extract-plugin": "^0.8.0",
"node-sass": "^4.14.1",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"postcss-loader": "^3.0.0",
"prettier": "^1.18.2",
"resolve-url-loader": "^4.0.0",
"sass-loader": "^8.0.0",
"style-loader": "^1.0.0",
"stylelint": "^11.0.0",
"stylelint-config-recommended-scss": "^4.0.0",
"stylelint-config-wordpress": "^15.0.0",
"stylelint-order": "^3.1.1",
"stylelint-scss": "^3.11.1",
"stylelint-webpack-plugin": "^1.0.1",
"svg-sprite-loader": "^4.1.6",
"svgo": "^1.3.0",
"svgo-loader": "^2.2.1",
"uglifyjs-webpack-plugin": "^2.2.0",
"url-loader": "^4.1.1",
"webpack": "^4.41.0",
"webpack-cli": "^3.3.9",
"wp-pot-cli": "^1.5.0"
},
"dependencies": {
"@babel/polyfill": "^7.6.0",
"imagemin": "^8.0.0",
"jquery": "^3.6.0"
}
}
解决方案
我过去遇到过类似的问题,我从文档中尝试了以下内容,
const ASSET_PATH = process.env.ASSET_PATH || '/';
export default {
output: {
publicPath: ASSET_PATH,
},
plugins: [
// This makes it possible for us to safely use env vars on our code
new webpack.DefinePlugin({
'process.env.ASSET_PATH': JSON.stringify(ASSET_PATH),
}),
],
};
但实际上,最适合我的问题的方法如下,而公共路径是提供资产的 CDN 链接
require('dotenv').config();
__webpack_public_path__ = config.publicPath // publicPath is process.env.ASSET_PATH || '/';
当您设置时,publicPath as "../"
您是否也尝试过useRelativePaths: true
?
参考:- https://github.com/webpack-contrib/file-loader#userelativepath
推荐阅读
- android - 使用 AAPT2 包含多个资源源的正确方法是什么?
- html - 外部文件中的 SVG 图标未在 Firefox 中呈现
- python - python3中的语法For
- flutter - 如何知道 SwitchListTile 中的字幕是否为两行或多行?
- ssh - 从 Ansible 在目标服务器上堆积的开放 ssh 连接的问题
- php - docker-compose mysql 拒绝用户 symfony@'172.18.0.1' 的访问
- c# - 如何让程序的下一部分在某个时间运行?
- python - 如何在html中的不同框中获取搜索结果
- python - 改进代码以使用 twitter API 查找追随者的追随者
- sql - SQL根据非空其他列查找最大日期