以前,咱們在項目裏會常常使用 process.env.NODE_ENV
, 但這個變量對於 webpack
打包是有影響的, 在 production
的時候是有優化的.node
因此, 咱們將改用其餘的環境變量來區別:webpack
new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"', 'process.env.API_ENV': `"${process.env.API_ENV || 'development'}"` })
像這樣, NODE_ENV
始終爲 production
.git
而咱們實際開發/產品環境, 用 process.env.API_ENV
變量來使用(因爲該項目是一個 koa 接口服務項目, 因此這樣進行命名, 能夠改爲任意的, 你開心就好).github
咱們之前在 node.js 後端項目中, 動態配置加載通常是這樣寫:web
const ENV = process.env.NODE_ENV || 'development'; // eslint-disable-next-line import/no-dynamic-require const options = require(`./_${ENV}`); module.exports = options;
爲了提升閱讀性, 和可能存在ENV
的複用, 咱們會單獨定義一個變量. 後端
在 webpack 打包的項目中直接這樣作的話, 會產生一個問題. 好比我如今有多個配置:服務器
即使我傳入的當前環境爲 development
, 依然全部的配置文件會被所有打包進來(只是永遠不會被執行). 那麼這樣的話, 就存在敏感信息泄露的風險.babel
正確的姿式應該是這樣的:app
// eslint-disable-next-line import/no-dynamic-require const options = require(`./_${process.env.API_ENV || 'development'}`); module.exports = options;
好比, 我在項目中有不少個模塊, 處於負載均衡的需求, 或者是對於客戶定製模塊化產品的需求, 咱們須要分模塊進行打包, 避免其餘模塊(永遠不會被執行的)被打包進 webpack bundle.負載均衡
// config/_development.js exports.enabledModules = ['user', 'demo']; // 可能 src 目錄下 還有其餘模塊目錄, 如 'manage' 等
在服務端加載的時候, 是這樣子的:
// src/server.js // 動態加載啓用的模塊 enabledModules.forEach((mod) => { /* eslint-disable global-require,import/no-dynamic-require */ const routes = require(`./${mod}/route`); routes.middleware() |> app.use; });
那麼就須要 ContextReplacementPlugin
插件來支持了.
new webpack.ContextReplacementPlugin(/src/, new RegExp(`^./(${enabledModules.join('|')})/.*$`))
好比,src
目錄下除了各個模塊的目錄, 還有一些通用方法類,鉤子的目錄, 如: lib
和 hook
. 這兩個目錄是可能被其餘子模塊共同引用的. 在插件正則中修改:
new webpack.ContextReplacementPlugin(/src/, new RegExp(`^./(lib|hook|${enabledModules.join('|')})/.*$`))
Uglifyjs
或 Uglify-es
其實對於服務器端代碼打包並不友好, 可能會致使打包的失敗, 用 babel-minify-webpack-plugin
插件來替代.
配合 source-map-support
插件來支持源碼的問題定位.