Изменение имени класса Webpack + angularjs + es6 в производственной среде - PullRequest
1 голос
/ 07 марта 2019


В моем проекте используются 3 файла веб-пакета (один общий и два для dev / prod env) и файл .babelrc для конфигурации babel

.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
    }
});

проблема в том, что когда я делаю dev build, es6имена классов остаются неизменными, но когда я делаю сборку prod, имена классов es6 меняются, и это нарушает процесс DI angularjs.

ПРИМЕР:
Допустим, есть 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)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...