尝试访问node_modules时,使用Angular 7构建的Webpack 4使sass-loader出现问题 [英] Webpack 4 build with Angular 7 gives problem with the sass-loader when trying to access to node_modules

查看:149
本文介绍了尝试访问node_modules时,使用Angular 7构建的Webpack 4使sass-loader出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从Angular v4升级到v7.由于.angular-cli.json对angular.json及其结构的影响,存在一些重大变化.然后还升级了angular和webpack的版本会产生影响.

I was working on a upgrade from Angular v4 to v7. There are some breaking changes due to the .angular-cli.json to angular.json and their structure. And then also upgrading the versions of angular and webpack has its impact.

在Angular 4中,它与自定义webpack生成器一起使用时效果很好,但是升级到v7具有其复杂性.还值得一提的是,在我使用的node_modules的scss中尝试在没有任何 @imports 的情况下进行构建也可以按预期工作.因此,我看到问题出在Webpack的路径中.

In Angular 4 it has worked fine with the custom webpack builder but upgrading to v7 has its complications. It is also worth mentioning that trying the build without any @imports in the scss on the node_modules that I use does work as expected too. So I see that the issue comes with the path to/from the webpack.

我们现在遇到的主要问题是sass-loader正在抱怨 @import'path/to/file',找不到它,然后构建失败.

The main issue we have right now is that the sass-loader is compaining about the @import 'path/to/file' that it doesn't find it and then fails the build.

进行 ng服务 ng构建确实可以正常工作,但是使用自定义Webpack进行构建确实会失败,因为它找不到路径.

Doing ng serve and ng build does work without any problem, but doing the build with the custom webpack it does fail because it doesn't find the path.

我得到的错误是:

模块构建中的错误失败(来自./node_modules/sass-loader/lib/loader.js):@import'../../styles/src/abstracts/_mixins.scss;^找不到或不可读的导入文件:'../../styles/src/abstracts/_mixins.scss;父样式表:stdin在/Path/to/project中(第4行,第1列)

ERROR in Module build failed (from ./node_modules/sass-loader/lib/loader.js): @import '../../styles/src/abstracts/_mixins.scss"; ^ File to import not found or unreadable: '../../styles/src/abstracts/_mixins.scss"; Parent style sheet: stdin in /Path/to/project (line 4, column 1)

我还尝试了从本地计算机到node_modules的软件包中的 npm link ,没有任何进展.

I have also tried doing npm link from the package from my local machine to the node_modules without any progress.

这些包是我在项目中导入的组件,它只是包含组件及其scss的包.

The packages are components that I import in my projects, it is only packages with components and its scss.

webpack配置文件如下所示:

The webpack config files looks like this:

* 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"
"to-string-loader":"1.1.5"
"ts-node":"7.0.1"
"typescript":"3.2.4"
"webpack":"4.29.0"
"webpack-cli":"3.3.10"
"webpack-merge":"4.2.2"
节点8.9.5和npm 5.5.1

Versions I use for this. "@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"
"to-string-loader": "1.1.5"
"ts-node": "7.0.1"
"typescript": "3.2.4"
"webpack": "4.29.0"
"webpack-cli": "3.3.10"
"webpack-merge": "4.2.2"
And node 8.9.5 with npm 5.5.1

谢谢!

推荐答案

我遇到了同样的问题,并使用 scss 的以下规则通过 sass-loader 解决了该问题 webpack.config.common.js :

I had the same issue and I resolved it with sass-loader applying the following rule for scss the 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 语句:

If you have another library in node_module that you need to use you can add another else if statement:

示例,假设我在 node_modules 中有一个自定义库 my-library ,并且我想访问: node_modules/my-library/style.scss,所以我必须添加以下 else if 语句:

Example, let's say I have a custom library my-library in node_modules and I want to access to: node_modules/my-library/style.scss so I have to add the following else if statement:

       {
            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;
                            },
                        },
                    }
                }
            ]
        }

算上这是我的项目结构:

Take in count that this was my project structure:

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

让我知道这是否对您有用.

Let me know if this works for you.

这篇关于尝试访问node_modules时,使用Angular 7构建的Webpack 4使sass-loader出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆