Управление WebPack без фреймворка - PullRequest
0 голосов
/ 29 ноября 2018

У нас есть стандартное (простое) ASP.NET Core MVC приложение - мы просто используем JavaScript для выполнения некоторых базовых улучшений пользовательского интерфейса.Мы используем 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());
})();

Мой вопрос заключается в том, как, учитывая среду, в которой я работаю, я могу улучшить этот подход.

Любое руководство будет оченьвысоко ценится.

...