在生产环境中更改Webpack + angularjs + es6类名称

时间:2019-03-07 09:18:18

标签: javascript angularjs webpack


我的项目正在使用3个webpack文件(一个常见,两个用于dev / prod env),而.babelrc文件用于babel config

.babelrc

{
  "presets": ["@babel/preset-env"],
  "plugins": ["angularjs-annotate"]
}

webpack.common.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const webpack = require("webpack");
const WebpackBar = require('webpackbar');

const pathPublic = "/public/path/";
const pathFonts = "/fonts/";


module.exports = {
    devtool: "eval",
    entry: {
        app: "./src/js/app.index.js",
    },
    module: {
        rules: [{
            test: /\.(gif|png|jpe?g)$/i,
            use: ["file-loader"],
        }, {
            test: /\.(woff|woff2|ttf|eot|svg|otf)(\?v=\d+\.\d+\.\d+)?$/,
            use: [{
                loader: 'file-loader',
                options: {
                    publicPath: pathPublic + pathFonts,
                    name: "[name].[ext]",
                    outputPath: pathFonts,
                    chunks: true
                }
            }]
        }, {
            test: /\.css$/,
            use: [
                {loader: "style-loader"},
                {loader: MiniCssExtractPlugin.loader},
                {loader: "css-loader"}
            ]
        }, {
            test: /\.scss$/,
            use: [
                {loader: "style-loader"},
                {loader: MiniCssExtractPlugin.loader},
                {loader: "css-loader"},
                {loader: "sass-loader"}
            ]
        }, {
            test: /\.less$/,
            use: [
                {loader: "style-loader"},
                {loader: MiniCssExtractPlugin.loader, options: {publicPath: pathPublic}},
                {loader: "css-loader"},
                {loader: "less-loader"}
            ]
        }]
    },
    plugins: [
        new WebpackBar(),
        new CleanWebpackPlugin(["frontend/dist", "static/"], {root: __dirname + "/.."}),
        new webpack.HotModuleReplacementPlugin(),
        new HtmlWebpackPlugin({
            collapseWhitespace: false,
            template: path.join(__dirname, "src/assets/html/index.proto.html"),
            title: 'SC app front page',
            inject: "html",
            hash: true
        }),
        new ScriptExtHtmlWebpackPlugin({defaultAttribute: "defer"}),
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery',
        }),
        new MiniCssExtractPlugin({
            filename: "styles.min.css",
        })
    ],
    stats: {
        children: false,
        colors: true
    },
};

webpack.prod.js

const merge = require('webpack-merge');
const common = require('./webpack.common');
const path = require('path');
const pathDist = path.resolve(__dirname, "dist");
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');


module.exports = merge(common, {
    mode: "production",
    output: {
        filename: "[name].min.js",
        publicPath: "/public/path/",
        chunkFilename: "npm.[id].[chunkhash].min.js",
        path: pathDist
    },
    optimization: {
        runtimeChunk: "single",
        minimizer: [
            new UglifyJsPlugin({
                sourceMap: false,
                uglifyOptions: {
                    compress: true,
                    output: {comments: false},
                }
            }),
            new OptimizeCssAssetsPlugin({
                assetNameRegExp: /\.(css|sass|scss|less)$/g,
                cssProcessor: require("cssnano")({
                    safe: true,
                    normalizeWhitespaces: true,
                    discardDuplicates: true,
                    discardComments: {
                        removeAll: true,
                    }
                })
            })
        ],
        splitChunks: {
            chunks: "all",
            maxInitialRequests: Infinity,
            cacheGroups: {
                vendor: {
                    test: /[\\/]node_modules[\\/]/,
                    maxSize: 249856, // 244 KiB Webpack recommended size
                },
            }
        },
    }
});

webpack.dev.js

const merge = require('webpack-merge');
const common = require('./webpack.common');
const path = require('path');
const pathDist = path.resolve(__dirname, "dist");
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');


module.exports = merge(common, {
    mode: "development",
    devtool: "inline-source-map",
    output: {
        filename: "[name].min.js",
        publicPath: "/public/path/",
        chunkFilename: "npm.[id].[chunkhash].min.js",
        path: pathDist
    },
    optimization: {
        minimizer: [
            new UglifyJsPlugin({
                sourceMap: true,
                uglifyOptions: {
                    compress: true,
                    output: {comments: false}
                }
            }),
            new OptimizeCssAssetsPlugin({
                assetNameRegExp: /\.(css|sass|scss|less)$/g,
                cssProcessor: require("cssnano")({
                    safe: true,
                    normalizeWhitespaces: true,
                    discardDuplicates: true,
                    discardComments: {
                        removeAll: true,
                    },
                })
            })
        ]
    },
    devServer: {
        contentBase: pathDist
    }
});

问题在于,当我进行开发时,es6类名称保持不变,但是当我进行生产时,es6类名称发生变化,这将导致angularjs DI进程崩溃。

示例:
假设有2个类(一个服务和一个控制器)

/**
 * build-dev: MyService.prototype.constructor.name = "MyService"
 * build-prod: MyService.prototype.constructor.name = "MyService__MyService"
 */
class MyService {
    serviceMethod() {
        // DO STUFF
    }
}

/**
 * build-dev: MyCtrl.prototype.constructor.name = "MyCtrl"
 * build-prod: MyCtrl.prototype.constructor.name = "MyCtrl__MyCtrl"
 */
class MyCtrl {
    constructor(MyService) {
        this.MyService = MyService;
    }

    ctrlMethod() {
        this.MyService.serviceMethod()
    }
}

并且这些类都以这种方式向angularjs DI注册了

angular.module("MyApp")
    .controller(MyCtrl.prototype.constructor.name, MyCtrl)
    .service(MyService.prototype.constructor.name, MyService)

现在请注意类注释(build-dev,build-prod)

0 个答案:

没有答案