WebPack-如何将WebPack配置为将全局和模块化的CS捆绑在一起



我目前正在从事一个Angular 2项目,并使用WebPack 2用于捆绑代码和资产。Angular应用程序使用bootstrap和styles.css全面包含一些全局样式。

此外,Angular成分本身具有单独的.CSS文件中的自己的样式表。请参见下面的文件结构:

app/index.html
app/styles.css
app/component/component.js
app/component/component.html
app/component/component.css

目前,webpack将所有这些文件既将.css and .js and .js都捆绑在一起,因此我有以下输出(CSS合并到JavaScript中):

dist/index.html
dist/js/app.bundle.js

我主要存在的问题是,这是创建一个fouc(未经风格的内容的闪光) - 从我的理解中,修复它的方法正在更改CSS将CSS拆分到其自己的文件中,以便可以由它不稳定地加载。浏览器 - 使用提取物text-webpack-plugin。

这很好,除了使用这种方法,我剩下的另一个问题。我失去了通过 component.css.css 文件提供的模块化CS的能力...

所以我有以下2个问题:

1。)如何将WebPack配置为仅将Bootstrap和我的样式提取到例如" dist/styles.css",但将其余的"非全球" CSS文件捆绑在一起,作为WebPack创建我的JavaScript捆绑包的一部分?

2。)是否可以将此提取的CSS注入index.html的头部部分。

new HtmlWebpackPlugin({
    filename: 'index.html',
    inject: 'body',
    template: 'ngApp/index.html'
})

(这是这样,我不必将HREF刻录到可能会改变WebPack配置的输出路径。)

我目前解决此问题的解决方案是使用copy-webpack-plugin移动bootstrap.min.css 和styles.css.css to dist 并在index.html中使用硬编码链接 - 但我不喜欢该设置。欢迎任何建议。

谢谢。

以防万一仍然相关:我设法找到了您第一个问题的解决方案,因为我试图为Spring Boot应用程序构建Angular 4前端,并面临完全相同的问题。这是我的webpack.config.js:

// Helper: root() is defined at the bottom
var path = require('path');
var webpack = require('webpack');
// Webpack Plugins
var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
var autoprefixer = require('autoprefixer');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
/**
 * Env
 * Get npm lifecycle event to identify the environment
 */
var ENV = process.env.npm_lifecycle_event;
var isProd = ENV === 'build';
module.exports = function makeWebpackConfig() {
    /**
     * Config
     * Reference: http://webpack.github.io/docs/configuration.html
     * This is the object where all configuration gets set
     */
    var config = {};
    /**
     * Devtool
     * Reference: http://webpack.github.io/docs/configuration.html#devtool
     * Type of sourcemap to use per build type
     */
    if (isProd) {
        config.devtool = 'source-map';
    }
    else {
        config.devtool = 'eval-source-map';
    }
    /**
     * Entry
     * Reference: http://webpack.github.io/docs/configuration.html#entry
     */
    config.entry = {
        'polyfills': './src/main/frontend/polyfills.ts',
        'vendor': './src/main/frontend/vendor.ts',
        'style': './src/main/frontend/style/global.scss',   // global styles
        'app': './src/main/frontend/main.ts'                // angular app
    };
    /**
     * Output
     * Reference: http://webpack.github.io/docs/configuration.html#output
     */
    config.output = {
        path: root('src/main/webapp'),
        publicPath: isProd ? '/' : 'http://localhost:8080/',
        filename: 'js/[name].js',
        chunkFilename: '[id].chunk.js'
    };
    /**
     * Resolve
     * Reference: http://webpack.github.io/docs/configuration.html#resolve
     */
    config.resolve = {
        // only discover files that have those extensions
        extensions: ['.ts', '.js', '.json', '.css', '.scss', '.html']
    };
    /**
     * Loaders
     * Reference: http://webpack.github.io/docs/configuration.html#module-loaders
     * List: http://webpack.github.io/docs/list-of-loaders.html
     * This handles most of the magic responsible for converting modules
     */
    config.module = {
        rules: [
            // Support for .ts files.
            {
                test: /.ts$/,
                use: ['awesome-typescript-loader', 'angular2-template-loader', '@angularclass/hmr-loader', 'angular2-router-loader'],
                exclude: [/.(spec|e2e).ts$/, /node_modules/(?!(ng2-.+))/]
            },
            // copy those assets to output
            {
                test: /.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)(?v=[0-9].[0-9].[0-9])?$/,
                use: 'file-loader?name=fonts/[name].[ext]?'
            },
            // Support for *.json files.
            {
                test: /.json$/,
                loader: 'json-loader'
            },
            // build global css bundle from src/main/frontend/style/global.css
            {
                test: /global.(css|scss)/,
                use: ExtractTextPlugin.extract(['css-loader', 'sass-loader'])
            },
            // all css required in src/main/frontend files will be merged in js files
            {
                test: /.(css|scss|sass)$/,
                loader: 'raw-loader!postcss-loader!sass-loader',
                exclude: [/global.(css|scss)/]
            },
            // support for .html as raw text
            // todo: change the loader to something that adds a hash to images
            {
                test: /.html$/,
                use: 'raw-loader'
            }
        ]
    };
    /**
     * Plugins
     * Reference: http://webpack.github.io/docs/configuration.html#plugins
     * List: http://webpack.github.io/docs/list-of-plugins.html
     */
    config.plugins = [
        // Define env variables to help with builds
        // Reference: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
        new webpack.DefinePlugin({
            // Environment helpers
            'process.env': {
                ENV: JSON.stringify(ENV)
            }
        }),

        // Workaround needed for angular 2 angular/angular#11580
        new webpack.ContextReplacementPlugin(
            // The (\|/) piece accounts for path separators in *nix and Windows
            /angular(\|/)core(\|/)(esm(\|/)src|src)(\|/)linker/,
            root('./src/main/frontend') // location of your src
        ),
        new webpack.LoaderOptionsPlugin({
            options: {
                /**
                 * PostCSS
                 * Reference: https://github.com/postcss/autoprefixer-core
                 * Add vendor prefixes to your css
                 */
                postcss: [
                    autoprefixer({
                        browsers: ['last 2 version']
                    })
                ]
            }
        }),
        // Generate common chunks if necessary
        // Reference: https://webpack.github.io/docs/code-splitting.html
        // Reference: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
        new CommonsChunkPlugin({
            name: ['app', 'vendor', 'polyfills']
        }),
        // Extract css files
        // Reference: https://github.com/webpack/extract-text-webpack-plugin
        // Disabled when in test mode or not in build mode
        new ExtractTextPlugin({
            filename: 'css/[name].min.css'
        })
    ];
    // Add build specific plugins
    if (isProd) {
        config.plugins.push(
            // Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
            // Only emit files when there are no errors
            new webpack.NoEmitOnErrorsPlugin(),
            // Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
            // Minify all javascript, switch loaders to minimizing mode
            new webpack.optimize.UglifyJsPlugin({sourceMap: true, mangle: {keep_fnames: true}}),

            // optimize CSS assets
            // Reference: https://github.com/NMFR/optimize-css-assets-webpack-plugin
            new OptimizeCssAssetsPlugin({
                assetNameRegExp: /.css$/g,
                cssProcessor: require('cssnano'),
                cssProcessorOptions: {
                    discardComments:
                        {
                            removeAll: true
                        }
                },
                canPrint: true
            }),
            // // Reference: https://github.com/webpack-contrib/webpack-bundle-analyzer
            new BundleAnalyzerPlugin({
                // Can be `server`, `static` or `disabled`.
                // In `server` mode analyzer will start HTTP server to show bundle report.
                // In `static` mode single HTML file with bundle report will be generated.
                // In `disabled` mode you can use this plugin to just generate Webpack Stats JSON file by setting `generateStatsFile` to `true`.
                analyzerMode: 'static',
                // Host that will be used in `server` mode to start HTTP server.
                analyzerHost: '127.0.0.1',
                // Port that will be used in `server` mode to start HTTP server.
                analyzerPort: 8888,
                // Path to bundle report file that will be generated in `static` mode.
                // Relative to bundles output directory.
                reportFilename: root('./report.html'),
                // Module sizes to show in report by default.
                // Should be one of `stat`, `parsed` or `gzip`.
                // See "Definitions" section for more information.
                defaultSizes: 'parsed',
                // Automatically open report in default browser
                openAnalyzer: false,
                // If `true`, Webpack Stats JSON file will be generated in bundles output directory
                generateStatsFile: false,
                // Name of Webpack Stats JSON file that will be generated if `generateStatsFile` is `true`.
                // Relative to bundles output directory.
                statsFilename: 'stats.json',
                // Options for `stats.toJson()` method.
                // For example you can exclude sources of your modules from stats file with `source: false` option.
                // See more options here: https://github.com/webpack/webpack/blob/webpack-1/lib/Stats.js#L21
                statsOptions: null,
                // Log level. Can be 'info', 'warn', 'error' or 'silent'.
                logLevel: 'info'
            })
        );
    }
    return config;
}();
// Helper functions
function root(args) {
    args = Array.prototype.slice.call(arguments, 0);
    return path.join.apply(path, [__dirname].concat(args));
}

最新更新