使用 Angular 7 构建的 Webpack 4 在尝试访问 node_modules 时会出现 sass-loader 问题
Posted
技术标签:
【中文标题】使用 Angular 7 构建的 Webpack 4 在尝试访问 node_modules 时会出现 sass-loader 问题【英文标题】:Webpack 4 build with Angular 7 gives problem with the sass-loader when trying to access to node_modules 【发布时间】:2020-05-11 01:55:39 【问题描述】:我正在从 Angular v4 升级到 v7。由于 .angular-cli.json 到 angular.json 及其结构,存在一些重大变化。然后升级 angular 和 webpack 的版本也会产生影响。
在 Angular 4 中,它与自定义 webpack 构建器配合得很好,但升级到 v7 有其复杂性。还值得一提的是,在我使用的 node_modules 上的 scss 中尝试没有任何 @imports
的构建也可以按预期工作。所以我看到问题来自于 webpack 的路径。
我们现在遇到的主要问题是 sass-loader 对 @import 'path/to/file'
感到不满,它没有找到它,然后构建失败。
执行ng serve
和ng build
确实没有任何问题,但是使用自定义webpack 构建它确实会失败,因为它找不到路径。
我得到的错误是:
模块构建失败(来自 ./node_modules/sass-loader/lib/loader.js): @import '../../styles/src/abstracts/_mixins.scss"; ^ 找不到或无法读取要导入的文件:'../../styles/src/abstracts/_mixins.scss"; 父样式表:stdin 在 /Path/to/project 中(第 4 行,第 1 列)
我也尝试过从本地机器到 node_modules 的包中的 npm link
没有任何进展。
这些包是我在项目中导入的组件,它只是带有组件及其 scss 的包。
webpack 配置文件如下所示:
* webpack.config.app.prod.js *
var webpackMerge = require('webpack-merge');
var prod = require('./webpack.config.prod');
var AotPlugin = require('@ngtools/webpack').AngularCompilerPlugin;
module.exports = webpackMerge.strategy(
plugins: 'prepend'
)(prod.config,
entry: './src/main-wp.editor.aot.ts',
output:
filename: 'editor.bundle.js',
chunkFilename: '[id].chunk.js',
library: '_' + 'child',
libraryTarget: 'jsonp'
,
plugins: [
new AotPlugin(
tsConfigPath: 'tsconfig.aot.json',
entryModule: './src/app/modules/app.module#EditorModule',
debug: true
)
]
);
* webpack.config.prod.js *
var path = require('path');
var webpack = require('webpack');
var webpackMerge = require('webpack-merge');
var commonConfig = require('./webpack.config.common');
var UglifyJsPlugin = require("uglifyjs-3-webpack-plugin");
module.exports =
config: webpackMerge(commonConfig,
output:
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
filename: 'bundle.js',
chunkFilename: '[id].[hash].chunk.js'
,
module:
rules: [
test: /\.ts$/,
use: ['@ngtools/webpack']
,
test: /\.js$/,
loader: '@angular-devkit/build-optimizer/webpack-loader',
options:
sourceMap: false
]
,
plugins: [
new UglifyJsPlugin(
uglifyOptions:
warnings: false,
ie8: false,
output:
comments: false
)
]
),
buildPath: function root(args)
var _root = path.resolve(__dirname);
args = Array.prototype.slice.call(arguments, 0);
return path.join.apply(path, [_root].concat(args));
;
* webpack.config.common.js *
var htmlWebpackPlugin = require('html-webpack-plugin');
var glob = require("glob");
var path = require('path');
module.exports =
entry: './src/main.ts',
resolve:
extensions: ['.js', '.ts']
,
module:
rules: [
test: /\.html$/,
loaders: ['html-loader']
,
test: /\.scss$/,
use: [
loader: "to-string-loader"
,
loader: "css-loader", // translates CSS into CommonJS
options:
sourceMap: true
,
loader: "sass-loader", // compiles Sass to CSS
options:
sourceMap: true,
includePaths: glob.sync(
path.join(__dirname, '**/node_modules/@mypackage/styles/src/abstracts')
).map((dir) => path.dirname(dir)),
// includePaths: [path.resolve("node_modules/@mypackage")],
// includePaths: [
// path.resolve('../node_modules')
// ]
]
],
exprContextCritical: false
,
plugins: [
new HtmlWebpackPlugin(
template: 'src/index.html'
)
]
;
我为此使用的版本。 "@angular/compiler-cli": "7.2.15" “uglifyjs-3-webpack-plugin”:“1.2.4” "@angular-builders/custom-webpack": "7.4.3" "@ngtools/webpack": "7.0.7", “@types/node”:“8.9.5” “node-sass”:“4.5.3” “sass-loader”:“7.3.1” “到字符串加载器”:“1.1.5” “ts-node”:“7.0.1” “打字稿”:“3.2.4” “webpack”:“4.29.0” “webpack-cli”:“3.3.10” “webpack 合并”:“4.2.2” 和节点 8.9.5 和 npm 5.5.1
谢谢!
【问题讨论】:
【参考方案1】:我遇到了同样的问题,我通过 sass-loader
将以下规则应用于 scss
webpack.config.common.js
解决了它:
test: /\.component\.(css|sass|scss)$/,
use: [
'to-string-loader',
'css-loader',
loader: 'sass-loader',
options:
sassOptions:
importer: url =>
if (url.startsWith('@angular/'))
return
file: path.resolve(`./node_modules/$url`),
;
return null;
,
,
]
如果您需要使用 node_module
中的另一个库,您可以添加另一个 else if
语句:
例如,假设我在node_modules
中有一个自定义库my-library
,我想访问:node_modules/my-library/style.scss
,所以我必须添加以下else if
语句:
test: /\.component\.(css|sass|scss)$/,
use: [
'to-string-loader',
'css-loader',
loader: 'sass-loader',
options:
sassOptions:
importer: url =>
if (url.startsWith('@angular/'))
return
file: path.resolve(`./node_modules/$url`),
;
else if (url.startsWith('my-library/'))
return
file: path.resolve(`./node_modules/$url`),
;
return null;
,
,
]
考虑一下这是我的项目结构:
node_modules
dist
config
- webpack.common.js
- webpack.dev.js
- webpack.prod.js
- webpack.test.js
src
- app
- app-routing.module.ts
- app.component.html
- app.component.scss
- app.component.ts
- app.module.ts
- index.ts
- index.html
- main.browser.ts
- polyfills.browser.ts
angular.json
package.json
postcss.config.js
tsconfig.json
tsconfig.webpack.json
webpack.config.js
让我知道这是否适合你。
【讨论】:
嗨@gquinteros93!我喜欢你拥有的 sassOptions,但它对我不起作用。如果值得一提,在我在这里提到的这个错误之前,我得到了另一个错误,我通过在我的本地包中执行npm link
和在项目文件夹中执行 npm link packageName
解决了这个错误。这样我就解决了第一个问题(请参阅此链接的最后一条评论。[***.com/questions/43037590/…)我不知道这是否与此有关?我已经尝试了所有可能的解决方案,但没有任何好的解决方案。感谢您的帮助!以上是关于使用 Angular 7 构建的 Webpack 4 在尝试访问 node_modules 时会出现 sass-loader 问题的主要内容,如果未能解决你的问题,请参考以下文章
使用 Angular 7 + Webpack 4 封装 css
“模板解析错误:'app' 不是已知元素”当使用 Webpack2 构建和部署“OK”angular2 应用程序时
Angular Webpack ES2015 组件构建中未触发 angular-ui-router $stateChangeStart 事件