使用 Webpack 解析从 node_modules 到 Dist 文件夹的相对路径
Resolve Relative Path from node_modules to Dist folder with Webpack
我将 React 组件用作 NPM 包。在组件中,我有 SCSS 文件
使用 url(../iamges/img..) 路径,但实际上,图像文件夹位于 Dist 文件夹中,我如何指向 Webpack 从 node_modules 获取相对路径并提供它来自 Dist 中的图像文件夹?
located in node_modules =>
background: url('../images/some-icon.svg') no-repeat center center;
Webpack 配置:
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: './src/index.js',
devtool: 'inline-module-source-map',
output: {
path: path.resolve(__dirname, '/dist'),
filename: 'bundle.js',
publicPath: '/',
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.scss$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{
loader: 'resolve-url-loader',
// options: {
// debug: true,
// root: path.join(__dirname, './dist/images'),
// includeRoot: true,
// absolute: true,
// },
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
sourceMapContents: false,
},
},
],
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
use: {
loader: 'url-loader?name=/images/[name].[ext]',
options: {
limit: 10000,
},
},
},
],
},
resolve: {
extensions: ['.js', '.jsx'],
// modules: [path.resolve(__dirname, '/images'), 'node_modules'],
alias: {
'react-redux': path.resolve('./node_modules/react-redux'),
},
},
plugins: [new webpack.HotModuleReplacementPlugin()],
devServer: {
hot: true,
publicPath: '/dist/',
},
};
babel.config.js
module.exports = {
// presets: ['@babel/preset-env', '@babel/preset-react'],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-export-default-from',
'@babel/transform-runtime',
],
sourceType: 'unambiguous',
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
'@babel/preset-react',
],
};
dist
-- images
-- index.html
错误:
ERROR in ./node_modules/comp/src/styles/details.scss (./node_modules/css-loader!./node_modules/resolve-url-loader!./node_modules/sass-loader/lib/loader.js??ref--5-3!./node_modules/compdetails/src/styles/details.scss)
Module not found: Error: Can't resolve '../images/icon.svg'
在css中通过url('...')
引用的任何内容都将参考已部署应用程序的路径进行计算(scss将不会计算路径,除非未使用变量或函数):
例如:
如果您引用的组件 SCSS 模块具有 background: url('../images/some-icon.svg') no-repeat center center;
最终的CSS编译将是相同的(这也是因为组件没有使用任何SCSS变量或函数来计算最终路径)。
所以您的应用程序将始终尝试找到该图像:
示例:http://localhost:3000/../images/some-icon.svg
这是一个问题。
(..
称为父目录)
如果您尝试 运行 您的应用程序带有一些子 url(也称为子上下文)作为 http://localhost:3000/sub-url/
,并且您使图像与 sub-url
平行文件夹它会自动工作。
-- /
|
|-- sub-url
|
|-- index.html
|-- images
|
|-- some-icon.svg
另一个选项可以用你的覆盖组件 SCSS。
您已经找到使用resolve-url-loader
的解决方案,但在这种情况下您需要将组件的scss文件导入您的scss.
因此您的 webpack 配置 应该如下所示:
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: './src/index.js',
devtool: 'inline-module-source-map',
output: {
path: path.resolve(__dirname, '/dist'),
filename: 'bundle.js',
publicPath: '/',
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.scss$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
// CHANGE HERE
{
loader: 'resolve-url-loader',
options: {
root: '/images', // considering all your images are placed in specified folder. Note: this is just a string that will get as prefix to image path
includeRoot: true,
absolute: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
sourceMapContents: false,
},
},
],
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
use: {
loader: 'url-loader?name=/images/[name].[ext]',
options: {
limit: 10000,
},
},
},
],
},
resolve: {
extensions: ['.js', '.jsx'],
// modules: [path.resolve(__dirname, '/images'), 'node_modules'],
alias: {
'react-redux': path.resolve('./node_modules/react-redux'),
},
},
plugins: [new webpack.HotModuleReplacementPlugin()],
devServer: {
hot: true,
publicPath: '/dist/',
},
};
希望对您有所帮助。
我将 React 组件用作 NPM 包。在组件中,我有 SCSS 文件 使用 url(../iamges/img..) 路径,但实际上,图像文件夹位于 Dist 文件夹中,我如何指向 Webpack 从 node_modules 获取相对路径并提供它来自 Dist 中的图像文件夹?
located in node_modules =>
background: url('../images/some-icon.svg') no-repeat center center;
Webpack 配置:
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: './src/index.js',
devtool: 'inline-module-source-map',
output: {
path: path.resolve(__dirname, '/dist'),
filename: 'bundle.js',
publicPath: '/',
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.scss$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{
loader: 'resolve-url-loader',
// options: {
// debug: true,
// root: path.join(__dirname, './dist/images'),
// includeRoot: true,
// absolute: true,
// },
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
sourceMapContents: false,
},
},
],
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
use: {
loader: 'url-loader?name=/images/[name].[ext]',
options: {
limit: 10000,
},
},
},
],
},
resolve: {
extensions: ['.js', '.jsx'],
// modules: [path.resolve(__dirname, '/images'), 'node_modules'],
alias: {
'react-redux': path.resolve('./node_modules/react-redux'),
},
},
plugins: [new webpack.HotModuleReplacementPlugin()],
devServer: {
hot: true,
publicPath: '/dist/',
},
};
babel.config.js
module.exports = {
// presets: ['@babel/preset-env', '@babel/preset-react'],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-export-default-from',
'@babel/transform-runtime',
],
sourceType: 'unambiguous',
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
'@babel/preset-react',
],
};
dist
-- images
-- index.html
错误:
ERROR in ./node_modules/comp/src/styles/details.scss (./node_modules/css-loader!./node_modules/resolve-url-loader!./node_modules/sass-loader/lib/loader.js??ref--5-3!./node_modules/compdetails/src/styles/details.scss)
Module not found: Error: Can't resolve '../images/icon.svg'
在css中通过url('...')
引用的任何内容都将参考已部署应用程序的路径进行计算(scss将不会计算路径,除非未使用变量或函数):
例如:
如果您引用的组件 SCSS 模块具有 background: url('../images/some-icon.svg') no-repeat center center;
最终的CSS编译将是相同的(这也是因为组件没有使用任何SCSS变量或函数来计算最终路径)。
所以您的应用程序将始终尝试找到该图像:
示例:http://localhost:3000/../images/some-icon.svg
这是一个问题。
(..
称为父目录)
如果您尝试 运行 您的应用程序带有一些子 url(也称为子上下文)作为 http://localhost:3000/sub-url/
,并且您使图像与 sub-url
平行文件夹它会自动工作。
-- /
|
|-- sub-url
|
|-- index.html
|-- images
|
|-- some-icon.svg
另一个选项可以用你的覆盖组件 SCSS。
您已经找到使用resolve-url-loader
的解决方案,但在这种情况下您需要将组件的scss文件导入您的scss.
因此您的 webpack 配置 应该如下所示:
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: './src/index.js',
devtool: 'inline-module-source-map',
output: {
path: path.resolve(__dirname, '/dist'),
filename: 'bundle.js',
publicPath: '/',
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.scss$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
// CHANGE HERE
{
loader: 'resolve-url-loader',
options: {
root: '/images', // considering all your images are placed in specified folder. Note: this is just a string that will get as prefix to image path
includeRoot: true,
absolute: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
sourceMapContents: false,
},
},
],
},
{
test: /\.css$/,
loaders: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
use: {
loader: 'url-loader?name=/images/[name].[ext]',
options: {
limit: 10000,
},
},
},
],
},
resolve: {
extensions: ['.js', '.jsx'],
// modules: [path.resolve(__dirname, '/images'), 'node_modules'],
alias: {
'react-redux': path.resolve('./node_modules/react-redux'),
},
},
plugins: [new webpack.HotModuleReplacementPlugin()],
devServer: {
hot: true,
publicPath: '/dist/',
},
};
希望对您有所帮助。