您现在的位置是:亿华云 > IT科技类资讯
Web Bundler CheatSheet, 选择合适的构建打包工具
亿华云2025-10-02 19:02:18【IT科技类资讯】5人已围观
简介Web Bundler CheatSheet | Web 构建与打包工具盘点工欲善其事,必先利其器,当我们准备开始某个 Web 相关的项目时,合适的脚手架会让我们事半功倍。在 2016-我的前端之路:
Web Bundler CheatSheet | Web 构建与打包工具盘点
工欲善其事,选择必先利其器,合适当我们准备开始某个 Web 相关的建打具项目时,合适的包工脚手架会让我们事半功倍。在 2016-我的选择前端之路:工具化与工程化一文中,我们讨论了工具化与工程化相关的合适内容,其中重要的建打具章节就是关于所谓的打包工具。Grunt、包工Glup 属于 Task Runner,选择即任务执行器; 实际上,合适npm package.json 中定义的建打具脚本也可以看做 Task Runner,而 Rollup,包工Parcel 以及 Webpack 则是选择属于 Bundler,即打包工具。合适
尺有所短,建打具寸有所长,不同的构建工具有其不同的适用场景。Webpack 是非常优秀的构建与打包工具,但是其提供了基础且复杂的功能支持,服务器租用使得并不适用于全部的场景。Parcel 这样的零配置打包工具适合于应用型的原型项目构建,而 Rollup 或者 Microbundle 适合于库的打包,Backpack 则能够帮我们快速构建 Node.js 项目。笔者在本文中列举讨论的仅是日常工作中会使用的工具,更多的 Browserify、Fusebox 等等构建工具查看 Web 构建与打包工具资料索引或者现代 Web 开发实战/进阶篇。
Parcel
Parcel 是著名的零配置的应用打包工具,在 TensorflowJS 或者 gh-craft 等算法实验/游戏场景构建中,都能够快速地搭建应用。
# 安装 Parcel $ npm install -g parcel-bundler # 启动开发服务器 $ parcel index.html # 执行线上编译 $ parcel build index.js # 指定编译路径 $ parcel build index.js -d build/outputParcel 会为我们自动地下载安装依赖,并且内置了 ES、SCSS 等常见的处理器。在 fe-boilerplate 中提供了 React, React & TypeScript, Vue.js 等 Parcel 常见的示例,这里以 React 为例,首先定义组件与渲染:
// index.js import React from react; import ReactDOM from react-dom; import logo from ../public/logo.svg; import ./index.css; const App = () => ( <div className="App"> <img className="App-Logo" src={ logo} alt="React Logo" /> <h1 className="App-Title">Hello Parcel x React</h1> </div> ); ReactDOM.render(<App />, document.getElementById(root)); // Hot Module Replacement if (module.hot) { module.hot.accept(); }然后定义入口的 index.html 文件:
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Parcel React Example</title> </head> <body> <div id="root"></div> <script src="./index.js"></script> </body> </html>然后使用 parcel index.html 运行开发服务器即可。Parcel 中同样也是支持异步加载的,高防服务器假设我们将部分代码定义在 someModule.js 文件中,然后在用户真实需要时再进行加载:
// someModule.js console.log(someModule.js loaded); module.exports = { render: function(element) { element.innerHTML = You clicked a button; } };在入口文件中使用 import 进行异步加载:
console.log(index.js loaded); window.onload = function() { document.querySelector(#bt).addEventListener(click, function(evt) { console.log(Button Clicked); import(./someModule).then(function(page) { page.render(document.querySelector(.holder)); }); }); };***值得一提的是,Parcel 内建支持 WebAssembly 与 Rust,通过简单的 import 导入,即可以使用 WASM 模块:
// synchronous import import { add} from ./add.wasm; console.log(add(2, 3)); // asynchronous import const { add} = await import(./add.wasm); console.log(add(2, 3)); // synchronous import import { add} from ./add.rs; console.log(add(2, 3)); // asynchronous import const { add} = await import(./add.rs); console.log(add(2, 3));这里 add.rs 是使用 Rust 编写的简单加法计算函数:
#[no_mangle] pub fn add(a: i32, b: i32) -> i32 { return a + b }Rollup 是较为为纯粹的模块打包工具,其相较于 Parcel 与 Webpack 等,更适合于构建 Library,譬如 React、Vue.js、Angular、D3、Moment、Redux 等一系列优秀的库都是采用 Rollup 进行构建。。Rollup 能够将按照 ESM(ES2015 Module)规范编写的源码构建输出为 IIFE、AMD、CommonJS、UMD、ESM 等多种格式,并且其较早地支持 Tree Shaking,Scope Hoisting 等优化特性,保证模块的简洁与高效。云南idc服务商这里我们使用的 Rollup 示例配置项目存放在了 fe-boilerplate/rollup。最简单的 rollup.config.js 文件配置如下:
export default { // 指定模块入口 entry: src/scripts/main.js, // 指定包体文件名 dest: build/js/main.min.js, // 指定文件格式 format: iife, // 指定 SourceMap 格式 sourceMap: inline };如果我们只是对简单的 sayHello 函数进行打包,那么输出的文件中也只是会简单地连接与调用,并且清除未真实使用的模块:
(function() { use strict; ... function sayHelloTo(name) { ... } ... const result1 = sayHelloTo(Jason); ... })(); //# sourceMappingURL=data:application/json;charset=utf-8;base64,...Rollup 同样具有丰富的插件系统,在 fe-boilerplate/rollup 中我们也引入了常见的别名、ESLint、环境变量定义、包体压缩与分析等插件。这里我们以最常用的 Babel 与 TypeScript 为例,如果我们需要在项目中引入 Babel,则同样在根目录配置 .babelrc 文件,然后引入 rollup-plugin-babel 插件即可:
import { rollup } from rollup; import babel from rollup-plugin-babel; rollup({ entry: main.js, plugins: [ babel({ exclude: node_modules/** }) ] }).then(...)对于 TypeScript 则是引入 rollup-plugin-typescript 插件:
import typescript from rollup-plugin-typescript; export default { entry: ./main.ts, plugins: [typescript()] };Microbundle 则是 Developit 基于 Rollup 封装的零配置的轻量级打包工具,其目前已经内建支持 TypeScript 与 Flow,不需要额外的配置;笔者在 js-swissgear/x-fetch 项目的打包中也使用了该工具。
{ "scripts": { "build": "microbundle", "dev": "microbundle watch" } } index.js 是 CommonJS 模块,是 Node.js 内置的模块类型,使用类似于 require(MyModule) 语法导入 index.m.js 是 ECMAScript 模块,使用类似于 import MyModule from my-module 语法导入 index.umd.js 是 UMD 模块 index.d.ts 是 TypeScript 的类型声明文件Webpack
作为著名的打包工具,Webpack 允许我们指定项目的入口地址,然后自动将用到的资源,经由 Loader 与 Plugin 的转换,打包到包体文件中。Webpack 相关的项目模板可以参考:fe-boilerplate/react-webpack, fe-boilerplate/react-webpack-ts, fe-boilerplate/vue-webpack 等。
Webpack 目前也支持零配置运行
$ npm install webpack webpack-cli webpack-dev-server --save-dev "scripts": { "start": "webpack-dev-server --mode development", "build": "webpack --mode production" },基础配置
const config = { // 定义入口 entry: { app: path.join(__dirname, app) }, // 定义包体文件 output: { // 输出目录 path: path.join(__dirname, build), // 输出文件名 filename: [name].js // 使用 hash 作为文件名 // filename: "[name].[chunkhash].js", }, // 定义如何处理 module: { rules: [ { test: /\.js$/, use: babel-loader, exclude: /node_modules/ } ] }, // 添加额外插件操作 plugins: [new webpack.DefinePlugin()] };Webpack 同样支持添加多个配置:
module.exports = [{ entry: ./app.js, output: ..., ... }, { entry: ./app.js, output: ..., ... }]我们代码中的 require 与 import 解析规范,则由 resolve 模块负责,其包含了扩展、别名、模块等部分:
const config = { resolve: { alias: { /*...*/ }, extensions: [ /*...*/ ], modules: [ /*...*/ ] } };资源加载
const config = { module: { rules: [ { // **Conditions** test: /\.js$/, // Match files enforce: pre, // "post" too // **Restrictions** include: path.join(__dirname, app), exclude: path => path.match(/node_modules/), // **Actions** use: babel-loader } ] } }; // Process foo.png through url-loader and other matches import url-loader!./foo.png; // Override possible higher level match completely import !!url-loader!./bar.png;babel-loader 或者 awesome-typescript-loader 来处理 JavaScript 或者 TypeScript 文件
/很赞哦!(8533)
上一篇: 如何防止数据中心中断?
下一篇: 绿色计算:可持续技术转变和城市采矿