在没有框架的情况下管理WebPack

时间:2018-11-29 15:47:38

标签: optimization webpack .net-core webpack-4

我们有一个标准(简单)的 ASP.NET Core MVC 应用程序-我们只是使用 JavaScript 来执行一些基本的UI增强。我们正在使用 TypeScript 来管理脚本-大多数/所有脚本都严重依赖 jQuery MomentJs 。在表示方面,我们还使用了 Bootstrap 4 FontAwesome

经过研究,我们决定尝试使用 WebPack 4 ,并提出了以下webpack.config.js

const environment = (process.env.NODE_ENV || 'development').toLowerCase().trim();
const isProduction = environment === 'production';

const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CssNano = require('cssnano');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const WebPack = require('webpack');

module.exports = {
    entry: {
        appScripts: './Src/appScripts.ts',
        appStyles: './Src/appStyles.scss',
        homePage: './Src/ts/pages/home.ts'
    },
    output: {
        path: path.resolve(__dirname, 'wwwroot'),
        filename: '[name].js'
    },
    resolve: {
        extensions: ['.ts', 'tsx', '.js', '.json']
    },
    module: {
        rules: [
            // JavaScript
            {
                test: /\.jsx?$/, // JavaScript and Reactive JavaScript
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader' // Transpiles ES6 JavaScript files
                }
            },

            // TypeScript
            {
                test: /\.tsx?$/,
                loader: 'ts-loader',
                exclude: /node_modules/
            },

            // CSS
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader', 'postcss-loader']
            },

            // SCSS
            {
                test: /\.scss$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    {
                        loader: 'css-loader', // translates CSS into CommonJS modules
                        options: {
                            modules: false,
                            minimize: isProduction,
                            sourceMap: !isProduction
                        }
                    },
                    {
                        loader: 'postcss-loader', // Run post css actions
                        options: {
                            plugins() {
                                // post css plugins, can be exported to postcss.config.js
                                return [
                                    require('precss'),
                                    require('autoprefixer')
                                ];
                            }
                        }
                    },
                    {
                        loader: 'sass-loader', // compiles SASS to CSS
                        options: {
                            sourceMap: !isProduction
                        }
                    }
                ]
            },

            // Fonts
            {
                test: /\.woff2?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                use: [
                    {
                        loader: 'url-loader?limit=10000&mimetype=application/font-woff',
                        options: {
                            name: '[name].[ext]',
                            outputPath: 'fonts/'
                        }
                    }
                ]
            },
            {
                test: /\.(ttf|eot|svg)(\?[\s\S]+)?$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[name].[ext]',
                            outputPath: 'fonts/'
                        }
                    }
                ]
            },

            // Images
            {
                test: /\.(png|jpe?g|gif|svg)$/i,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[name].[ext]',
                            outputPath: 'images/'
                        }
                    }
                ]
            },

            // Font-Awesome
            {
                test: /font-awesome\.config\.js/,
                use: [
                    { loader: 'style-loader' },
                    { loader: 'font-awesome-loader' }
                ]
            }
        ]
    },
    plugins: [
        // Make jQuery globally accessible
        new WebPack.ProvidePlugin({
            '$': 'jquery',
            'jQuery': 'jquery',
            'window.jQuery': 'jquery'
        }),

        // Ignore all locale files of moment.js
        new WebPack.IgnorePlugin(/^\.\/locale$/, /moment$/),

        // Extract CSS from JavaScript modules
        new MiniCssExtractPlugin({
            filename: '[name].css'
        }),

        // Configure MomentJs Locales
        new MomentLocalesPlugin({
            localesToKeep: ['en-gb']
        }),

        // Copy favicon.ico and all other static image assets
        new CopyWebpackPlugin([
                {
                    from: 'Src/img/*.ico',
                    to: './',
                    flatten: true
                },
                {
                    from: 'Src/img',
                    to: 'images',
                    ignore: '*.ico'
                }
            ],
            {
                debug: 'info'
            }),

        // Clean up wwwroot
        new CleanWebpackPlugin([
                'app*.*',
                '*.js',
                'images'
            ],
            {
                root: path.resolve(__dirname, 'wwwroot'),
                verbose: false,
                dry: false
            })
    ],
    optimization: {
        minimize: isProduction,     // Toggle optimization
        minimizer: [
            new UglifyJsPlugin({ sourceMap: !isProduction }),
            new OptimizeCSSAssetsPlugin({
                assetNameRegExp: /\.css$/g,
                cssProcessor: CssNano,
                cssProcessorOptions: {
                    preset: [
                        'default', {
                            discardComments: {
                                removeAll: true
                            }
                        }
                    ]
                },
                canPrint: true
            })
        ]
        // splitChunks: {
        //     chunks: 'all'
        // }
    },
    devtool: isProduction ? null : 'source-map'
};

我不知道这是多么理想,或者即使这是正确的方法,但它确实创建了.js,并且可以在所需的脚本文件(JavaScript,CSS,字体和图像)中使用创建并加载页面。

以下是结果:

appScripts.js   21,867,327 
appStyles.css      228,085 
appStyles.js         3,763 
homePage.js        694,263 

当然,问题在于,这是一个很大的有效负载,对于每个页面加载,它都作为单个文件被调用。

作为参考,这里是appScripts.ts文件,其目的是增强网站上使用的标准页面布局(最终它将做得更多)...

// Import Bootstrap - this will pull in peer dependencies for
// jQuery and Popper
import 'bootstrap';

// Import the Font-Awesome loader to build Font-Awesome
import 'font-awesome-loader!./config/font-awesome.config.js';

// Import Moment-Timezone to get all of MomentJs
import * as moment from 'moment-timezone';

// Import all the common components
import './ts/components/LanguageSelector.ts'


(() => {
    console.log('JavaScript Libraries Loaded.');
    $('#language-selector').languageSelector();
    $('#label-locale').text(moment.locale());
    $('#label-timezone').text(moment.tz.guess());
})();

我的问题是,考虑到我所处的环境,我如何才能改进这种方法。

任何指导将不胜感激。

0 个答案:

没有答案