Webpack 服務器端代碼打包

環境變量

以前,咱們在項目裏會常常使用 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 打包的項目中直接這樣作的話, 會產生一個問題. 好比我如今有多個配置:服務器

  • _develpment.js
  • _test.js
  • _production.js
  • _staging.js

即使我傳入的當前環境爲 development, 依然全部的配置文件會被所有打包進來(只是永遠不會被執行). 那麼這樣的話, 就存在敏感信息泄露的風險.babel

正確的姿式應該是這樣的:app

config/index.js

// 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目錄下除了各個模塊的目錄, 還有一些通用方法類,鉤子的目錄, 如: libhook. 這兩個目錄是可能被其餘子模塊共同引用的. 在插件正則中修改:

new webpack.ContextReplacementPlugin(/src/, new RegExp(`^./(lib|hook|${enabledModules.join('|')})/.*$`))

壓縮代碼, 並添加 source-map 支持

UglifyjsUglify-es 其實對於服務器端代碼打包並不友好, 可能會致使打包的失敗, 用 babel-minify-webpack-plugin 插件來替代.

配合 source-map-support 插件來支持源碼的問題定位.


相關文章
相關標籤/搜索