Webpack 是一个打包工具,经常用於前端领域,能够将各个依赖的档案进行 bundle, 更提供了预处理的功能,使 sass
、ES6
等被翻译成浏览器看得懂的样子。
事实上後端与前端不同,大部分情况下 後端是没有打包的必要,也就是说使用 Webpack 打包後端并不是必要条件,但我会特地写一篇关於 Webpack 打包 Express 是有原因的,请大家先试着建置 production 版本并跑起来看看吧!
要记得先完善 production.env 的内容呦!
npm start
咦?怎麽会出错?
这个 secret
有点眼熟,没错,就是 JWT 要使用的值,这部分我们是将它写成环境变数去读取,表示环境变数的读取有问题,可以发现编译後的档案不包含 environments
下的所有档案,原因是 TypeScript Compiler 本身只编译 TS ,那要怎麽把环境变数档搬过去呢?最土法炼钢的方法就是写脚本复制一份到 dist
资料夹下,但还有另一条路可以走,就是使用 Webpack。
Webpack 对环境变数的处理 不是 将环境变数档的内容放入环境变数来 读取,而是将使用到环境变数档内容的程序码片段 抽换 成这些环境变数的值,什麽意思呢?以 JWT_SIGN
这个环境变数为例,以下是 JWT_SIGN
的范例内容:
JWT_SIGN=zxcdsaqwerfv
在没有经过预处理的情况下是透过 process.env.JWT_SIGN
去读取,并从记忆体中取得 zxcdsaqwerfv 这串字;经过预处理後,是会把程序码中出现 process.env.JWT_SIGN
的部分直接变成 zxcdsaqwerfv 这串字,这样的好处是 不用一直搬移档案 ,也 不需要花时间与空间去读取环境变数。
先透过 npm 安装 Webpack 与 Webpack CLI:
npm install webpack webpack-cli --save-dev
安装完毕後,还需要再安装 ts-loader,原因是要让 Webpack 知道该以什麽样的方式去读取档案并编译:
npm install ts-loader --save-dev
如果不希望把 node_modules
这个黑洞 一起打包的话,强烈建议安装 webpack-node-externals 这个套件:
npm install webpack-node-externals --save-dev
一切准备就绪!在专案目录下新增 webpack.config.js
,里面的内容即为 Webpack 的配置:
const path = require('path');
const webpack = require('webpack');
const dotenv = require('dotenv');
const nodeExternals = require('webpack-node-externals');
module.exports = (env, argv) => {
// 取得环境变数档的内容,并依照 mode 来切换模式
const params = dotenv.config({ path: path.resolve(__dirname, `./src/environments/${argv.mode}.env`) }).parsed;
// 将环境变数的设置写入 Object 中,以方便後续调用
const processEnv = {};
Object.keys(params).forEach(key => processEnv[`process.env.${key}`] = JSON.stringify(params[key]));
return {
entry: './src/index.ts', // 载入点
target: 'node', // 使用 node
externals: [
nodeExternals() // 排除 node_modules
],
module: {
rules: [
{
test: /\.ts$/, // .ts 的档案用 ts-loader 读取
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.ts', '.js'] // 补足 import 档案的结尾
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new webpack.DefinePlugin(processEnv) // 设置环境变数
]
}
};
在开发过程中一定会有热重载的需求,也就会想起我们的好朋友 nodemon,但要如何跟 Webpack 整合呢?就要安装 nodemon-webpack-plugin:
npm install nodemon-webpack-plugin --save-dev
并在 webpack.config.js
的 plugins
下使用:
plugins: [
new webpack.DefinePlugin(processEnv),
new NodemonPlugin()
]
由於有些操作权已经交给 Webpack,这边就可以把部分 TypeScript 的配置关闭:
{
"compilerOptions": {
"incremental": true, // 启用增量编译
"target": "ES2017", // 编译成指定的 JavaScript 版本
"module": "commonjs", // 指定编译成何种模组
"declaration": false, // 产生 '.d.ts' 档
"sourceMap": false, // 产生 '.map' 档
"rootDir": "./src", // 载入点的位置
"removeComments": true, // 移除注解
"strict": true, // 采用严格模式
"baseUrl": "./src", // 指定汇入档案的基准路径
"esModuleInterop": true, // 兼容模组
"experimentalDecorators": true, // 启用装饰器
"emitDecoratorMetadata": true // 提供装饰器 metadata
},
"include": ["src/**/*.ts"], // 纳入编译范围
"exclude": ["node_modules", "dist"] //不纳入编译范围
}
我们要来调整 npm script 的配置,如下:
"scripts": {
"start": "NODE_ENV=production node ./dist/main.bundle.js",
"start:dev": "webpack --mode=development --watch",
"start:prod": "webpack --mode=production --watch",
"build": "webpack --mode=production"
}
接着只要视情况使用就可以罗!
用 Webpack 打包後端虽然不是必要,但也是种选择,我认为能够稳定、方便开发与容易维护才是最重要的,要不要使用这个方法全看需求而定,各位有什麽看法呢?欢迎在下面讨论!
>>: [Android 开发经验三十天]D29一小画家小问题跟改善方法
为何想要一台 NAS? 备份档案,作为家里的网路磁碟机 当作小型服务器跑应用程序: 软件工程师手贱心...
这回写到的霍夫曼编码是在Algorithms Illuminated Part 3: Greedy ...
质数(Prime number) 在国中时有学过质数,质数除了1和本身之外,没有其他因数的大於1的自...
React 的表单验证篇总共会三篇,这篇我们会自己手刻一个验证输入值是否合法的表单,而在後面两篇文章...
天亮了 昨晚是平安夜 关於迷雾森林故事 洛神降临 图片来源 她就是洛神啊 以前只听过爸妈说过 这还是...