【问题标题】:Webpack 4 build with Angular 7 gives problem with the sass-loader when trying to access to node_modules使用 Angular 7 构建的 Webpack 4 在尝试访问 node_modules 时会出现 sass-loader 问题
【发布时间】: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 serveng 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

谢谢!

【问题讨论】:

    标签: angular webpack webpack-4 sass-loader


    【解决方案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 解决了这个错误。这样我就解决了第一个问题(请参阅此链接的最后一条评论。[stackoverflow.com/questions/43037590/…)我不知道这是否与此有关?我已经尝试了所有可能的解决方案,但没有任何好的解决方案。感谢您的帮助!
    猜你喜欢
    • 2020-11-07
    • 2018-09-11
    • 1970-01-01
    • 1970-01-01
    • 2017-02-16
    • 1970-01-01
    • 1970-01-01
    • 2017-06-14
    • 2011-05-29
    相关资源
    最近更新 更多