Skip to content

Webpack

Chaos edited this page Aug 21, 2020 · 5 revisions

Webpack

webpack能把所有的JS打包成一个JS文件,并能支持最新的JS特性,是现代化JS编程的一个重要工具。本项目的模板已经有一份配置,默认为根目录下的webpack.config.js,内容如下。

webpack.config.js

const path = require("path")
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const JavascriptObfuscator = require("webpack-obfuscator")
const AutoProWebpackPlugin = require('@auto.pro/webpack-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin


const dictionary = []
for (let i = 1024; i < 2048; i++) {
    dictionary.push(
        i
            .toString(2)
            .replace(/1/g, "ν")
            .replace(/0/g, "v")
    )
}

const compilePlugin = new AutoProWebpackPlugin({
    ui: ['app'],
    // encode: {
    //     key: ''
    // }
})

const config = {
    entry: {
        app: "./src/index.js"
    },
    output: {
        filename: "[name].js",
        path: path.resolve(__dirname, "dist"),
        libraryTarget: "var"
        // libraryTarget: "commonjs2"
    },
    target: "node",
    module: {
        rules: [
            {
                test: /\.ts$/,
                exclude: /node_modules/,
                use: ['ts-loader', '@auto.pro/webpack-loader']
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: ['babel-loader', '@auto.pro/webpack-loader']
            },
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: {
                    loader: "url-loader"
                }
            }
        ]
    },
    resolve: {
        extensions: [".js", ".ts", ".json"],
        alias: {
            "@": path.resolve(__dirname, "src")
        }
    }
}

module.exports = (env, argv) => {
    if (argv.mode === 'development') {
        config.plugins = [
            new CleanWebpackPlugin(),
            new BundleAnalyzerPlugin(),
            compilePlugin
        ]
        config.devtool = 'source-map'
    } else {
        config.plugins = [
            new CleanWebpackPlugin(),
            new JavascriptObfuscator({
                compact: true,
                identifierNamesGenerator: "dictionary",
                identifiersDictionary: dictionary,
                // 生成的代码环境,可选browser、browser-no-eval、node
                target: "browser-no-eval",
                // 混淆对象键名
                transformObjectKeys: false,
                // 将字符串明文转义为Unicode,会大大增加体积,还原也比较容易,建议只对小文件使用
                unicodeEscapeSequence: false
            }),
            compilePlugin
        ]
    }

    return config
}

配置项

config.entry

entry指定了入口和出口,键代表出口文件名,值代表入口路径。

output.libraryTarget

webpack提供了多种文件输出格式,你可以根据自己的情况进行配置。

  • 情景1(大多数场景)
    我们需要直接以项目方式运行,或直接以单个脚本方式运行,此时libraryTarget使用默认的var即可。

  • 情景2(制作模块)
    有时候我们想把功能抽离成模块,以便方便的复用,让其他JS文件能require或import这个模块,比如

// main.js
var m = require('打包出来的模块')

则需要将libraryTarget设置成commonjs2

@auto.pro/webpack-plugin

此插件提供了auto.pro的UI模式打包,并能进行AES代码加密,它有两个很简单的配置项

  • ui: string[]
    将数组内的文件进行UI模式打包,文件名对应webpack.config.js文件的entry
  • encode: { key: string }
    将所有文件进行加密输出,key为AES密钥,当encode缺省时不进行加密。
    加密方式使用的是AES/ECB/PKCS7padding加密,解密时也应该使用此类型,例如以下示例:解密dist/app.js并运行
const source = $crypto.decrypt(
  files.read('dist/app.js', 'utf8'),
  new $crypto.Key("SecretPassphrase"),  // 对应encode的key
  "AES/ECB/PKCS7padding",
  {
    input: "base64",
    output: "string",
  }
)
files.write('dist/main.js', source)
engines.execScriptFile('dist/main.js')

webpack-obfuscator

webpack-obfuscator插件提供了代码混淆的功能,需要自定义请看webpack-obfuscator