resolve-url-loader
我在我的 webpack 配置中正确设置时遇到问题。它似乎根本无法解析scss
文件中的路径。
这是我的项目文件夹结构:
├───config
│ └───jest
├───public
│ └───assets
│ ├───css
│ ├───fonts
│ ├───images
│ │ ├───background
│ │ ├───icons
│ │ ├───illustration
│ │ ├───logo
│ │ └───projects
│ │ ├───one
│ │ └───two
│ ├───js
│ └───scss
│ ├───blog
│ ├───common
│ ├───default
│ ├───elements
│ ├───header
│ └───template
├───scripts
└───src
├───component
│ ├───common
│ ├───footer
│ ├───header
│ └───slider
├───elements
│ ├───blog
│ ├───common
│ ├───portfolio
│ ├───projects
│ └───tab
└───home
下面你会发现它webpack.config.js
的样子。这有点复杂,但我试图隐藏所有我认为与解决此问题无关的代码块。use
通常,方法中的加载器链是由getStyleLoaders
文件开头定义的函数创建的。如果preProcessor
被标识为sass-loader
then 则另外resolve-url-loader
添加。问题是,在查看resolve-url-loader
's debug 时,它似乎无法从文件public
夹中的 scss 文件中解析 url。我得到的唯一调试日志如下:
Resolve-url-loader
调试日志:
resolve-url-loader: ./node_modules/slick-carousel/slick/slick-theme.css: ./ajax-loader.gif
./node_modules/slick-carousel/slick
FOUND
resolve-url-loader: ./node_modules/slick-carousel/slick/slick-theme.css: ./fonts/slick.eot
./node_modules/slick-carousel/slick
FOUND
resolve-url-loader: ./node_modules/slick-carousel/slick/slick-theme.css: ./fonts/slick.woff
./node_modules/slick-carousel/slick
FOUND
resolve-url-loader: ./node_modules/slick-carousel/slick/slick-theme.css: ./fonts/slick.ttf
./node_modules/slick-carousel/slick
FOUND
resolve-url-loader: ./node_modules/slick-carousel/slick/slick-theme.css: ./fonts/slick.svg
./node_modules/slick-carousel/slick
scss
我在“调试”日志中看不到的文件中定义了一些 url 链接。我究竟做错了什么?
webpack.config.js
细节:
'use strict';
/*some plugins*/
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const safePostCssParser = require('postcss-safe-parser');
const ManifestPlugin = require('webpack-manifest-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
/*some plugins*/
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
const paths = require('./paths');
const modules = require('./modules');
/*some plugins*/
const postcssNormalize = require('postcss-normalize');
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'true';
const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';
const useTypeScript = fs.existsSync(paths.appTsConfig);
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
module.exports = function(webpackEnv) {
const isEnvDevelopment = webpackEnv === 'development';
const isEnvProduction = webpackEnv === 'production';
// Webpack uses `publicPath` to determine where the app is being served from.
// It requires a trailing slash, or the file assets will get an incorrect path.
// In development, we always serve from the root. This makes config easier.
const publicPath = isEnvProduction
? paths.servedPath
: isEnvDevelopment && '/';
const shouldUseRelativeAssetPaths = publicPath === './';
const publicUrl = isEnvProduction
? publicPath.slice(0, -1)
: isEnvDevelopment && '';
// Get environment variables to inject into our app.
const env = getClientEnvironment(publicUrl);
// common function to get style loaders
const getStyleLoaders = (cssOptions, preProcessor) => {
const loaders = [
isEnvDevelopment && require.resolve('style-loader'),
isEnvProduction && {
loader: MiniCssExtractPlugin.loader,
options: shouldUseRelativeAssetPaths ? { publicPath: '../../' } : {},
},
{
loader: require.resolve('css-loader'),
options: cssOptions,
},
{
loader: require.resolve('postcss-loader'),
options: {
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
}),
postcssNormalize(),
],
sourceMap: isEnvProduction && shouldUseSourceMap,
},
},
].filter(Boolean);
if (preProcessor) {
if (preProcessor === "sass-loader") {
loaders.push({
loader: require.resolve('resolve-url-loader'),
options: cssOptions,
})
}
loaders.push({
loader: require.resolve(preProcessor),
options: {
sourceMap: isEnvProduction && shouldUseSourceMap,
},
});
}
return loaders;
};
return {
mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
bail: isEnvProduction,
devtool: isEnvProduction
? shouldUseSourceMap
? 'source-map'
: false
: isEnvDevelopment && 'cheap-module-source-map',
entry: [/*...*/].filter(Boolean),
output: {/*...*/},
optimization: {/*...*/},
resolve: {/*...*/},
resolveLoader: {/*...*/},
module: {
strictExportPresence: true,
rules: [
{ parser: { requireEnsure: false } },
{
/*es-lint loader*/
},
{
oneOf: [
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve('url-loader'),
options: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]',
},
},
{/*babel-loader*/},
},
{/*babel-loader*/},
{
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
}),
sideEffects: true,
},
{
test: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: true,
getLocalIdent: getCSSModuleLocalIdent,
}),
},
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
'sass-loader'
),
sideEffects: true,
},
{
test: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: true,
getLocalIdent: getCSSModuleLocalIdent,
},
'sass-loader'
),
},
{
loader: require.resolve('file-loader'),
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
},
],
},
plugins: [/*...*/].filter(Boolean),
node: {/*...*/},
performance: false,
};
};