Webpack [url/file-loader] 未解析 URL 的相对路径
Webpack [url/file-loader] is not resolving the Relative Path of URL
我在 Webpack 中遇到了一个关于相对路径的问题。
让我试着解释一下这个场景:
我在 Workspace 目录 中有 2 个单独的项目:
- Project-A [使用 Gulp 捆绑]:稳定且工作
- 项目-B [使用 Webpack 捆绑]:新建项目
因为两个项目都使用相同的样式,所以我想重用 [=43= 的 SCSS 文件 [由标准变量、预定义布局、模态、类 等组成] ]项目 A 到项目 B。
现在,如果我尝试将项目 A index.scss 导入项目 B index.scss 作为另一个部分 [ 注释掉背景图像 URL 依赖],webpack 能够生成所需的 CSS 输出文件。
// Import Project A SCSS [Common Varibles, Classes, Styling etc]
@import "../../../../Project_A/assets/stylesheets/index";
但是由于 Project-A 的 index.scss 进一步从各自的相对路径引用背景图像,webpack 构建会抛出错误
'File / dir not found in XYZ/Project-B/Source/Stylesheets'.
确切错误块:
ERROR in ./src/assets/stylesheets/index.scss
Module build failed: ModuleNotFoundError: Module not found: Error: Cannot resolve 'file' or 'diWorkSpace\Project_B\src\assets\stylesheets
截图:
我无法理解,为什么 Webpack 无法解析 Project-A 中资产的相对路径并仍在内部查找 'Project B'.
这是模拟问题的代码库 URL:
https://github.com/raviroshan/webpack-build-issue/tree/master/WorkSpace
重现步骤。
- 下载回购协议。
- 浏览 Project_B 文件夹,然后执行 NPM 安装。
- 运行'webpack'。它会正确构建为相对图像
URL 代码被注释掉了。
- 现在放回注释的代码行:https://github.com/raviroshan/webpack-build-issue/blob/master/WorkSpace/Project_A/assets/stylesheets/index.scss#L27
需要将publicPath设置为相对路径,才能获取file-loader中的相对路径。
它似乎是 css-loader 的错误以及它在 @import
和 url()
中解析路径的方式。它会尝试解析相对于主 CSS 文件的所有路径——甚至是那些来自导入样式表的路径——在你的例子中是 /Project_B/src/assets/stylesheets/index.scss
.
别哭!有解决办法!
也许它并不完美,但它是我迄今为止最好的。
创建一个全局变量 $assetsPath
保存资产路径 相对于当前样式表 。然后将此变量添加到所有 url()
值之前。
在你的 /Project_A/assets/stylesheets/index.scss
你会写:
/*/ Using !default we can override this variable even before the following line: /*/
$assetsPath: '../' !default;
.container {
/*/ ... /*/
.content-wrapper {
/*/ ... /*/
background-image: url($assetsPath + "images/content-bg.jpg");
}
}
在你的 /Project_B/src/assets/stylesheets/index.scss
你会写:
/*/ The following variable will override $assetsPath defined in the imported file: /*/
$assetsPath: '../../../../Project_A/assets/';
/*/ Import Project A SCSS [Common Varibles, Classes, Styling etc] /*/
@import "../../../../Project_A/assets/stylesheets/index";
后果
如果您将 Project-A 与 Gulp 捆绑在一起,它将看到 Project-A 的代码为:
/*/ ... /*/
background-image: url("../images/content-bg.jpg");
尽管如此,当您将 Project-B 与 Webpack 捆绑在一起时,它会看到 Project-A 的代码为:
/*/ ... /*/
background-image: url("../../../../Project_A/assets/images/content-bg.jpg");
因此,你得救了。
我肯定会仔细研究这个问题。如果 url-loader
尊重 @import
语句中的路径并将其相应地应用于引用的资产,那么所有这一切都可以避免。要么我遗漏了什么,要么应该将其视为错误。
希望你今天过得愉快!
~Wiktor
所以,经过这么多的努力,终于得到了一个合适的解决方案。
原来是 CSS-loader 的问题,即它无法解析与当前文件相关的 URL。
使用resolve-url-loader解决了这个问题。
https://www.npmjs.com/package/resolve-url-loader
// Old Loader Config in Webpack-entry
loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap!sass-loader?sourceMap')
// New [Fixed] Loader Config in Webpack-entry
loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap!resolve-url-loader!sass-loader?sourceMap')
此处已更新 Code-Repo 解决方案:https://github.com/raviroshan/webpack-build-issue
注意 : 不要省略 -loader
您的 Webpack.config.js 应始终使用加载程序名称的 long-form(即 -loader 后缀)。
还有一个名为 resolve-url 的包,Webpack 可能会与 resolve-url-loader 混淆。
我在 Webpack 中遇到了一个关于相对路径的问题。 让我试着解释一下这个场景:
我在 Workspace 目录 中有 2 个单独的项目:
- Project-A [使用 Gulp 捆绑]:稳定且工作
- 项目-B [使用 Webpack 捆绑]:新建项目
因为两个项目都使用相同的样式,所以我想重用 [=43= 的 SCSS 文件 [由标准变量、预定义布局、模态、类 等组成] ]项目 A 到项目 B。
现在,如果我尝试将项目 A index.scss 导入项目 B index.scss 作为另一个部分 [ 注释掉背景图像 URL 依赖],webpack 能够生成所需的 CSS 输出文件。
// Import Project A SCSS [Common Varibles, Classes, Styling etc]
@import "../../../../Project_A/assets/stylesheets/index";
但是由于 Project-A 的 index.scss 进一步从各自的相对路径引用背景图像,webpack 构建会抛出错误
'File / dir not found in XYZ/Project-B/Source/Stylesheets'.
确切错误块:
ERROR in ./src/assets/stylesheets/index.scss Module build failed: ModuleNotFoundError: Module not found: Error: Cannot resolve 'file' or 'diWorkSpace\Project_B\src\assets\stylesheets
截图:
我无法理解,为什么 Webpack 无法解析 Project-A 中资产的相对路径并仍在内部查找 'Project B'.
这是模拟问题的代码库 URL: https://github.com/raviroshan/webpack-build-issue/tree/master/WorkSpace
重现步骤。
- 下载回购协议。
- 浏览 Project_B 文件夹,然后执行 NPM 安装。
- 运行'webpack'。它会正确构建为相对图像 URL 代码被注释掉了。
- 现在放回注释的代码行:https://github.com/raviroshan/webpack-build-issue/blob/master/WorkSpace/Project_A/assets/stylesheets/index.scss#L27
需要将publicPath设置为相对路径,才能获取file-loader中的相对路径。
它似乎是 css-loader 的错误以及它在 @import
和 url()
中解析路径的方式。它会尝试解析相对于主 CSS 文件的所有路径——甚至是那些来自导入样式表的路径——在你的例子中是 /Project_B/src/assets/stylesheets/index.scss
.
别哭!有解决办法!
也许它并不完美,但它是我迄今为止最好的。
创建一个全局变量 $assetsPath
保存资产路径 相对于当前样式表 。然后将此变量添加到所有 url()
值之前。
在你的 /Project_A/assets/stylesheets/index.scss
你会写:
/*/ Using !default we can override this variable even before the following line: /*/
$assetsPath: '../' !default;
.container {
/*/ ... /*/
.content-wrapper {
/*/ ... /*/
background-image: url($assetsPath + "images/content-bg.jpg");
}
}
在你的 /Project_B/src/assets/stylesheets/index.scss
你会写:
/*/ The following variable will override $assetsPath defined in the imported file: /*/
$assetsPath: '../../../../Project_A/assets/';
/*/ Import Project A SCSS [Common Varibles, Classes, Styling etc] /*/
@import "../../../../Project_A/assets/stylesheets/index";
后果
如果您将 Project-A 与 Gulp 捆绑在一起,它将看到 Project-A 的代码为:
/*/ ... /*/
background-image: url("../images/content-bg.jpg");
尽管如此,当您将 Project-B 与 Webpack 捆绑在一起时,它会看到 Project-A 的代码为:
/*/ ... /*/
background-image: url("../../../../Project_A/assets/images/content-bg.jpg");
因此,你得救了。
我肯定会仔细研究这个问题。如果 url-loader
尊重 @import
语句中的路径并将其相应地应用于引用的资产,那么所有这一切都可以避免。要么我遗漏了什么,要么应该将其视为错误。
希望你今天过得愉快!
~Wiktor
所以,经过这么多的努力,终于得到了一个合适的解决方案。
原来是 CSS-loader 的问题,即它无法解析与当前文件相关的 URL。
使用resolve-url-loader解决了这个问题。 https://www.npmjs.com/package/resolve-url-loader
// Old Loader Config in Webpack-entry
loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap!sass-loader?sourceMap')
// New [Fixed] Loader Config in Webpack-entry
loader: ExtractTextPlugin.extract('style-loader', 'css-loader?sourceMap!resolve-url-loader!sass-loader?sourceMap')
此处已更新 Code-Repo 解决方案:https://github.com/raviroshan/webpack-build-issue
注意 : 不要省略 -loader 您的 Webpack.config.js 应始终使用加载程序名称的 long-form(即 -loader 后缀)。
还有一个名为 resolve-url 的包,Webpack 可能会与 resolve-url-loader 混淆。