用ts编写webpack配置

webpack是对ts项目进行混淆打包的最佳工具之一。

更方便的编写webpack配置也是ts项目开发的必修课。

首先,命令行安装webpack的所有全局依赖:

# 安装webpack及其代码提示到全局
npm install -g webpack webpack-cli @types/wabpack
# 安装terser-webpack-plugin及其代码提示插件到全局
npm install -g terser-webpack-plugin @types/terser-webpack-plugin

用vscode打开要用webpack打包的项目文件夹。

创建webpack/tsconfig.project.json,从项目tsconfig.json中复制内容至此文件,但需要更改以下配置:

// 删去outFile项(如果存在的话)
- outFile:xxx
// 增加或更改以下配置(让webpack采用commonjs模块方式编译ts项目)
"module": "commonjs"

创建webpack/config.ts文件

import path = require('path');

import * as TerserPlugin from 'terser-webpack-plugin';
import { Compiler, Configuration } from 'webpack';

/**
 * 项目路径
 */
const PROJECT_DIR = path.resolve(__dirname, '..');
/**
 * webpack使用的项目配置的路径
 */
const PROJECT_TSCONFIG_JSON = path.resolve(__dirname, 'tsconfig.project.json');

/**
 * 项目导出的文件夹,对应 tsconfig.json中的outDir
 */
const OUT_DIR = path.resolve('xxx');
/**
 * 导出文件名
 */
const OUT_FILENAME = 'xxx.js';

/**
 * 入口文件绝对路径数组
 */
const PROJECT_ENTRY_FILES = [
    "xxx.src"
    ...
];

/**
 * 库路径,对应tsconfig.json中的path项,但需要采用绝对路径
 */
const PROJECT_MODULE_ALIAS = {
    "xxx": xxxx
    ...
};

// 实现一个输出最终导出文件名的插件
class OutputPlugin
{
    constructor()
    {
        
    }

    apply(compiler: Compiler)
    {
        compiler.hooks.done.tapAsync('output', (stats, callback) =>
        {
            callback();
            const compilation = stats.compilation;
            const outputPath = compilation.outputPath || compilation.outputOptions.path;
            for (const filename in compilation.assets)
            {
                const filepath = path.resolve(outputPath, filename);
                console.log('[out]', filepath);
            }
        });
    }
}

/**
 * webpack的配置主体
 */
const webpack_config: Configuration =
{
    entry: PROJECT_ENTRY_FILES,
    // 输出
    output: {
        filename: OUT_FILENAME,
        path: OUT_DIR
    },
    stats: {
        builtAt: true,
        errorDetails: true
    },
    // 代码优化
    optimization: {
        /**
         * 代码最小化配置
         */
        minimizer: [
            /**
             * 代码混淆插件配置
             */
            new TerserPlugin({
                terserOptions: {
                    mangle: {
                        eval: true
                    }
                }
            })]
    },
    module: {
        rules: [
            {
                // 匹配所有ts文件
                test: /\.ts$/,
                loader: 'ts-loader',
                options:
                {
                    // 项目配置文件
                    configFile: PROJECT_TSCONFIG_JSON,
                    context: PROJECT_DIR
                }
            }
        ]
    },
    resolve: {
        // 依赖的库
        alias: PROJECT_MODULE_ALIAS,
        // 没有扩展名时候尝试添加的扩展
        extensions: [
            '.ts'
        ]
    },
    // ts-loader的解析路径
    resolveLoader: {
        modules: ([
            path.resolve(process.env['NODE_PATH'])
        ]).filter(uri => !!uri)
    },
    // 插件
    plugins: [
        new OutputPlugin()
    ],
    mode: "production"
}

module.exports = webpack_config;

执行:终端-运行任务

选择webpack/tsconfig.json编译

生成webpack/config.js

执行:终端-配置任务

选择任意任务,生成.vscode/tasks.json,然后对其进行修改如下:

// 省略其他配置
"tasks": [
    {
        // 任务名称
        "label": "webpack xxx",
        // 以shell方式执行
        "type": "shell",
        // 命令
        "command": "webpack",
        "args": [
            // 指定webpack配置文件名
            "--config",
            "${workspaceFolder}/webpack/common.js"
        ],
        "options": {
            // 因为采用了全局webpack,需指定NODE_PATH为全局npm路径,具体到node_modules文件夹
            "env": {
                "NODE_PATH": "xxxx/node_modules"
            }
        },
        "problemMatcher": []
    }
]

执行此任务即可。