Transpile Webpack Plugin:让 Webpack 按照源文件的目录结构输出

作为 Web 开发者,你是否也纠结过如何用 Webpack 做文件转译?就像 Babel CLI 转译文件那样按照源文件的目录结构输出?如果有,那么这篇文章就是为你而写,我们一起瞧一瞧怎么做吧。

Webpack 与 bundling

Screen Shot 2022-12-27 at 11.06.01.png

在平日的印象中,似乎 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 插件有着若干个可用的配置项,其中最有常用的两个可能是 longestCommonDirextentionMapping

默认情况下,Transpile 插件使用输入文件的共有目录作为基准目录计算各个输出文件在输出目录下的相对路径。但有时输入文件可能会在嵌套比较深的目录下面,如果我们想要保留这种嵌套结构,就可以使用 longestCommonDir。给定输入文件 src/server/index.jssrc/server/constants/greeting.js 和输出目录 dist,当这个配置为 undefined,输出文件会是 dist/index.jsdist/constants/greeting.js。而这个配置为 './src',输出文件会是 dist/server/index.jsdist/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,欢迎共同探讨。

认真写点好代码。

2.2k 声望
1.1k 粉丝
0 条评论
推荐阅读
再见了 Redux、Recoil、MobX、Zustand、Jotai 还有 Valtio,状态管理还可以这样做?
坚持在一线写前端代码大概有七八年了,写过一些项目,有过一些反思,越来越确信平日里一直用得心安理得某些的东西也许存在着问题,比如:在 状态管理 上一直比较流行的实践 🙏,所以试着分享出来探讨一下。

乌柏木3阅读 630

ESlint + Stylelint + VSCode自动格式化代码(2023)
安装插件 ESLint,然后 File -> Preference-> Settings(如果装了中文插件包应该是 文件 -> 选项 -> 设置),搜索 eslint,点击 Edit in setting.json

谭光志34阅读 20.8k评论 9

安全地在前后端之间传输数据 - 「3」真的安全吗?
在「2」注册和登录示例中,我们通过非对称加密算法实现了浏览器和 Web 服务器之间的安全传输。看起来一切都很美好,但是危险就在哪里,有些人发现了,有些人嗅到了,更多人却浑然不知。就像是给门上了把好锁,还...

边城32阅读 7.3k评论 5

封面图
涨姿势了,有意思的气泡 Loading 效果
今日,群友提问,如何实现这么一个 Loading 效果:这个确实有点意思,但是这是 CSS 能够完成的?没错,这个效果中的核心气泡效果,其实借助 CSS 中的滤镜,能够比较轻松的实现,就是所需的元素可能多点。参考我们...

chokcoco24阅读 2.3k评论 3

你可能不需要JS!CSS实现一个计时器
CSS现在可不仅仅只是改一个颜色这么简单,还可以做很多交互,比如做一个功能齐全的计时器?样式上并不复杂,主要是几个交互的地方数字时钟的变化开始、暂停操作重置操作如何仅使用 CSS 来实现这样的功能呢?一起...

XboxYan25阅读 1.7k评论 1

封面图
在前端使用 JS 进行分类汇总
最近遇到一些同学在问 JS 中进行数据统计的问题。虽然数据统计一般会在数据库中进行,但是后端遇到需要使用程序来进行统计的情况也非常多。.NET 就为了对内存数据和数据库数据进行统一地数据处理,发明了 LINQ (L...

边城17阅读 2k

封面图
过滤/筛选树节点
又是树,是我跟树杠上了吗?—— 不,是树的问题太多了!🔗 相关文章推荐:使用递归遍历并转换树形数据(以 TypeScript 为例)从列表生成树 (JavaScript/TypeScript) 过滤和筛选是一个意思,都是 filter。对于列表来...

边城18阅读 7.9k评论 3

封面图

认真写点好代码。

2.2k 声望
1.1k 粉丝
宣传栏