作为 Web 开发者,你是否也纠结过如何用 Webpack 做文件转译?就像 Babel CLI 转译文件那样按照源文件的目录结构输出?如果有,那么这篇文章就是为你而写,我们一起瞧一瞧怎么做吧。
Webpack 与 bundling
在平日的印象中,似乎 Webpack 就等于 bundling,就如官方文档首页写的那样 "bundle your ...",看上去 Webpack 就是来做 bundling 的。在浏览器上,bundles 确实很不错,能够以非常合理的策略加载和执行。但在 NodeJS 中,事情就变得有点不同了。
在 NodeJS 中,以分文件的方式组织和执行 JS 文件通常是更自然的实践,主要是因为源文件路径相关的逻辑有时是避免不了的,比如:在云函数或 Serverless 中注册事件、在某些 CLI 辅助下生成的源代码。然而,想要在这基础上添加服务端渲染(SSR)逻辑,考虑到前端部分可能已经用 Webpack 引用了各式各样的文件,后端部分可能也不得不用 Webpack 做 bundling。但这也意味着,我们不得不做相当量的工作来让 bundles 可以合理适配这些源文件路径相关的逻辑。
为了更轻松的在 NodeJS 中使用 Webpack,Transpile Webpack Plugin(transpile-webpack-plugin) 便诞生了。这个插件能够将 entry 引用到的全部文件列为输入文件,经过编译,再按照相同的目录格式输出到输出目录中。我们一起看一下用法吧。
基本用法
给定在目录 src
下有 2 个文件,其中一个导出字符串常量,另一个引用这个常量然后打印出来。初始的文件结构大体如下:
.
├── src/
│ ├── constants.js
│ └── index.js
├── package.json
└── webpack.config.js
现在,我们要把目录 src
下的文件使用 Webpack 转译到目录 dist
下,像这样:
.
├── dist/
│ ├── constants.js
│ └── index.js
...
首先,我们需要保证 webpack
(v5) 和 webpack-cli
(v4) 已经安装好:
$ npm i -D webpack webpack-cli
然后,安装 transpile-webpack-plugin
(v1):
$ npm i -D transpile-webpack-plugin
之后,调整 webpack.config.js
:
const TranspilePlugin = require('transpile-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: __dirname + '/dist',
},
plugins: [new TranspilePlugin()],
};
最后,执行 npx webpack
。这样,所有直接或间接被 entry 引用到的文件都会被收集为输入文件,之后,以输入文件的共有路径为基准目录,计算得到输出目录下各个文件的相对输出路径,再以这些路径生成输出文件,保留源文件的目录结构。我们可以通过 node dist/index.js
或查看生成的代码来验证输出。
处理 SSR
假设有前端部分已用 Webpack 搭建完毕,其中涉及了各种文件的转换和非 JS 静态资源的 emitting,现在想要在后端部分(NodeJS 服务器)做 SSR,但在运行时保留源文件的目录结构。
那么我们只需要复用前端部分的 Webpack 配置的基础上,关闭所有非 JS 静态资源的 emitting、将 new TranspilePlugin()
加入到 plugins 即可。Transpile 插件已经经过了严格测试可以完好兼容包括 resolve 别名、externals、source map 等在内的各种 Webpack 设置。
更多用法
Transpile 插件有着若干个可用的配置项,其中最有常用的两个可能是 longestCommonDir 和 extentionMapping。
默认情况下,Transpile 插件使用输入文件的共有目录作为基准目录计算各个输出文件在输出目录下的相对路径。但有时输入文件可能会在嵌套比较深的目录下面,如果我们想要保留这种嵌套结构,就可以使用 longestCommonDir。给定输入文件 src/server/index.js
、src/server/constants/greeting.js
和输出目录 dist
,当这个配置为 undefined
,输出文件会是 dist/index.js
、dist/constants/greeting.js
。而这个配置为 './src'
,输出文件会是 dist/server/index.js
、dist/server/constants/greeting.js
。
默认情况下,Transpile 插件生成的输出文件具有与输入文件相同的文件名。(NodeJS 会把不认识后缀的文件视为 JS 文件。)但有时我们会想变换一下文件后缀,比如从 .ts
变换为 .js
,那么通过配置项 extentionMapping 为 { '.ts': '.js' }
就可以做到。
讨论问题?
希望 Transpile Webpack Plugin(transpile-webpack-plugin) 让我们更轻松的在 NodeJS 中使用 Webpack。有任何问题或任何建议,可以在评论区留言或直接在 transpile-webpack-plugin/issues 发起 issue,欢迎共同探讨。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。