使用Postcss进行Webpack编译失败,因为在node_modules的库中找不到scss文件

时间:2019-12-27 14:11:55

标签: angular webpack postcss postcss-loader postcss-import

这是我的项目结构:

-match

当我尝试使用yarn编译或构建项目时,由于在node_modules中找不到scss文件而失败:

enter image description here

实际上,scss文件退出:

enter image description here

该文件属于有角flex layout

下面是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 ,它试图使用属于app.components.scss的{​​{1}}

layout-bp

我认为问题在于,当文件位于@angular/flex-layout/mq

中时,它正在尝试在@import '@angular/flex-layout/mq'; .top-bar { height: 25px; width: 100%; } .start-over { font-weight: bold; border-radius: 2.5px; .material-icons { margin-right: 5px; transform: scalex(-1); } span { font-size: 13px; vertical-align: middle; } &--mobile { display: none; .material-icons { transform: scalex(-1) translate(12px, -12px); } } } @media screen { @each $br in ('xs', 'sm') { @include layout-bp($br) { .start-over { margin-right: 8px; } } } } 中查找mq.scss文件。

要运行项目,请使用src/app/node_modules 该命令执行以下操作:    1)建立项目。    2)使用以下命令运行yarn start:consumer文件夹中的文件:yarn start

下面,我复制distnode dist/app.jspostcss.config.jswebpack.config.jswebpack.common.js

postcss.config.js

webpack.dev.js

webpack.config.js

package.json

webpack.common.js

module.exports = {
    parser: 'postcss-scss',
    plugins: {
        "postcss-import": {},
        'postcss-each': {},
        'postcss-at-rules-variables': {},
        'postcss-simple-vars': {},
        'precss': {},
        'postcss-functions': {},
        'cssnano': {},
        autoprefixer: {
            browsers: ['last 2 versions']
        },
    }
};

webpack.dev.js

switch (process.env.NODE_ENV) {
  case 'prod':
  case 'production':
    module.exports = require('./config/webpack.prod')({env: 'production'});
    break;
  case 'test':
  case 'testing':
    module.exports = require('./config/webpack.test')({env: 'test'});
    break;
  case 'dev':
  case 'development':
  default:
    module.exports = require('./config/webpack.dev')({env: 'development'});
}

package.json

const helpers = require('./helpers');
/*
 * Webpack Plugins
 */
const DefinePlugin = require('webpack/lib/DefinePlugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');

const buildUtils = require('./build-utils');

/*
 * Webpack configuration
 */
module.exports = function (options) {
    const METADATA = Object.assign({}, buildUtils.DEFAULT_METADATA, options.metadata || {});
    const supportES2015 = buildUtils.supportES2015(METADATA.tsConfigPath);
    const entry = {
        'polyfills': './src/polyfills.browser.ts',
        'main': './src/main.browser.ts'
    };

    return {
        entry: entry,
        resolve: {

            mainFields: [ ...(supportES2015 ? ['es2015'] : []), 'browser', 'module', 'main' ],
            extensions: ['.ts', '.js', '.json', '.css', '.scss'],
            modules: [helpers.root('src'), helpers.root('node_modules')],
            alias: buildUtils.rxjsAlias(supportES2015)
        },
        module: {

            rules: [

                {
                    test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
                    loader: '@ngtools/webpack'
                },
                {
                    test: /\.css$/,
                    use: ['to-string-loader', 'css-loader'],
                    exclude: [helpers.root('src', 'styles')]
                },
                {
                    test: /\.component\.(sass|scss)$/,
                    exclude: [helpers.root('src', 'styles')],
                    use: [
                        'to-string-loader',
                        { loader: 'css-loader', options: {importLoaders: 1, modules: true } },
                        'postcss-loader'
                    ]
                },
                {
                    test: /\.html$/,
                    use: 'raw-loader',
                    exclude: [helpers.root('src/index.html')]
                },
                {
                    test: /\.(jpg|png|gif|svg)$/,
                    loader: 'file-loader',
                    options: {
                        name: 'assets/[name].[hash].[ext]',
                    }
                 },
                {
                    test: /\.(eot|woff2?|svg|ttf)([\?]?.*)$/,
                    use: 'file-loader'
                }

            ],

        },
        plugins: [

            new DefinePlugin({
                'ENV': JSON.stringify(METADATA.ENV),
                'process.env.ENV': JSON.stringify(METADATA.ENV),
                'process.env.NODE_ENV': JSON.stringify(METADATA.ENV),
            }),
            new HtmlWebpackPlugin({
                chunksSortMode: 'none'
            }),
            new ScriptExtHtmlWebpackPlugin({
                sync: /inline|polyfills|vendor/,
                defaultAttribute: 'async',
                preload: [/polyfills|vendor|main/],
                prefetch: [/chunk/]
            }),
            new LoaderOptionsPlugin({}),
        ],
        node: {
            global: true,
            crypto: 'empty',
            process: true,
            module: false,
            clearImmediate: false,
            setImmediate: false
        }

    };
};

1 个答案:

答案 0 :(得分:2)

就像我在问题中说的那样,问题在于,当组件尝试从scss导入scss文件时,编译器无法编译组件的node_modules文件。

我使用sass-loader webpack.config.common.js 中为scss应用以下规则来解决该问题:

        {
            test: /\.component\.(css|sass|scss)$/,
            use: [
                'to-string-loader',                  
                'css-loader',
                'postcss-loader',
                {
                    loader: 'sass-loader',
                    options: {
                        sassOptions: {
                            importer: url => {
                                if (url.startsWith('@angular/')) {
                                    return {
                                        file: path.resolve(`./node_modules/${url}`),
                                    };
                                }
                                return null;
                            },
                        },
                    }
                }
            ]
        }

如果必须从node_module导入另一个库,则应该添加另一个if语句:

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

   {
        test: /\.component\.(css|sass|scss)$/,
        use: [
            'to-string-loader',                  
            'css-loader',
            'postcss-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;
                        },
                    },
                }
            }
        ]
    }

这样,我的项目又可以工作了。此外,它还可以使用buildserve进行编译。

最后,在我的 postcss.config.js 中,我只需要:

module.exports = {
    plugins: [
        require('autoprefixer')
    ]
}