1. gulp
1.1 gulp理论
glup的核心理念是task runner,定义一系列任务,然后使用gulp的插件体系来完成这些任务。但是gulp默认不支持模块化,不会帮你自动构建依赖,只是帮你完成你设定的任务。
webpack的核心理念是module bundler,是一个模块化的打包工具,通过loader来加载不同的模块,自动构建依赖树,可以进行tree shaking。
gulp相对于webpack的优缺点:
- gulp相对于webpack思想更加简单、易用,更适合编写一些自动化的任务。
- 但是目前对于大型项目(Vue、React、Angular)并不会使用gulp来构建,比如gulp默认是不支持模块化的。
1.2 gulp的基本使用
在控制台执行npx gulp jsTask,就会执行jsTask函数。
每次手动指定任务很麻烦,也可以设置默认任务,即执行 npx gulp 即可
module.exports.default = (cb) => {
console.log('默认任务执行');
cb();
}
上面每次执行的都是gulp的单任务,也可以一次执行多个任务,多个任务又分为串行和并行任务。
const { series, parallel } = require('gulp');
const task1 = (cb) => {
setTimeout(() => {
console.log("task1");
cb();
}, 2000);
}
const task2 = (cb) => {
setTimeout(() => {
console.log("task2");
cb();
}, 2000);
}
const task3 = (cb) => {
setTimeout(() => {
console.log("task3");
cb();
}, 2000);
}
const seriesTask = series(task1, task2, task3);
const parallelTask = parallel(task1, task2, task3);
const composeTask = series(parallelTask, seriesTask);
module.exports = {
seriesTask,
parallelTask,
composeTask
}
1.3 gulp文件监听
const { src, dest, watch } = require("gulp");
const babel = require("gulp-babel");
const uglify = require("gulp-uglify");
const terser = require("gulp-terser");
const jsTask = () => {
// 从src中读取文件, 输出到dist文件夹中
return (
src("./src/**/*.js")
.pipe(babel({ presets: ["@babel/preset-env"] }))
// .pipe(uglify())
.pipe(terser({ mangle: { toplevel: true } }))
.pipe(dest("./dist"))
);
};
watch("./src/**/*.js", jsTask);
module.exports = {
jsTask,
};
1.4 完整案例
2. Rollup中文网
Rollup 是一个 JavaScript 模块打包工具,常用于基础库的打包构建,与传统的 CommonJS 和 AMD 这一类非标准化的解决方案不同,Rollup 使用的是 ES6 版本 Javascript 中的模块标准。
React、Vue、Dayjs这些库都是使用的rollup打包。
webpack使用commonJs规范,你会发现在webpack中都是module.exports导出模块。
查看rollup提供了哪些功能 npx rollup --help
rollup的使用 - 不使用配置文件,在命令行使用
-f 是 --format
rollup的使用 - 使用配置文件
首先新建rollup.config.js
文件,然后在package.json的scripts出配置 build: rollup -c
,
其中rollup.config.js为es语法,如下:
export default {
input: 'src/main.js',
output: [
{
file: 'dist/bundle.js',
format: 'cjs'
},
{
file: 'dist/bundle-es.js',
format: 'es'
}
]
}
如果想对代码进行压缩,则需要使用plugins,可以在如下地址查询,例如terser
import terser from '@rollup/plugin-terser';
export default {
input: 'src/main.js',
output: [
{
file: 'dist/bundle.js',
format: 'cjs'
},
{
file: 'dist/bundle-es.js',
format: 'es'
}
],
plugins: [terser()]
}
rollup插件
rollupplugin-node-resolve插件
默认情况下,rollup不会把第三方库打入到bundle中,
比如:
import React from 'react';
rollup不会把第三方react打包进来,且会提示如下警告,这一点和Webpack是不一样的。
如果确实需要将第三方打包进来,则需要安装额外的插件:
https://cn.rollupjs.org/tools/#rollupplugin-node-resolve
如果使用这个插件,则会把所有引用的第三方库打进来,但是有时候又不需要打进来,如何处理呢?增加external配置,例如不需要将react打进来
external: ['react']
@rollup/plugin-commonjs插件
比如打包的文件中有
import React from 'react';
但是react默认的导出是commonJS,而rollup默认处理ESModule,所以会报错:https://cn.rollupjs.org/troubleshooting/#error-name-is-not-exported-by-module
解决方案是将react将commonJS规范转换为ESModule规范,因此需要@rollup/plugin-commonjs插件。
静态资源插件
rollup可以对图片、css等静态资源进行处理,如果将图片、css等抽离到单独的文件夹中,则还需要手动处理依赖关系。
因为,rollup的设计原则就是处理库文件,而库应用很少有图片等这类偏业务的资源。
因此,一般比较简单的做法是将静态资源都打包到.bundle.js文件中。
import del from 'rollup-plugin-delete';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import terser from "@rollup/plugin-terser";
import babel from '@rollup/plugin-babel';
import image from '@rollup/plugin-image';
import postcss from 'rollup-plugin-postcss';
import postcssImport from "postcss-import";
import postcssUrl from 'postcss-url';
import autoprefixer from "autoprefixer";
import json from '@rollup/plugin-json';
export default {
input: 'src/index.js',
output: [
{
file: 'dist/es/index.js',
format: 'es'
}
],
jsx: 'react',
external: ['react', 'react-dom', 'axios'],
plugins: [
del({ targets: 'dist/*' }),
resolve({
extensions: ['.js', '.jsx']
}),
commonjs(),
babel({
babelHelpers: 'bundled',
exclude: 'node_modules/**',
extensions: ['.js', '.jsx']
}),
postcss({
extensions: ['.css', '.scss'],
extract: false,
minimize: false,
sourceMap: false,
plugins: [
postcssImport(),
postcssUrl({
url: 'inline'
}),
autoprefixer(),
]
}),
image(),
json(),
terser()
]
};
rollup小结:
- Rollup用来打包核心库,也可以替代webpack打包项目;
- Rollup核心概念:input,output,format(打包成哪种规范),plugins;
- plugins的使用方式:顺序引入,顺序执行
Vite
Vite命令:
"scripts": {
"serve": "vite",
"build": "vite build",
"preview": "vite preview"
}
Vite为什么快?
- 在开发阶段不会打包bunding,而webpack在
开发阶段
会在内存
中打包bunding,Vite基于原生ES模块,充分利用浏览器的对es的支持。 - Vite会在本地启动一个http服务,通过http的request实现按需导入。-- 冷启动
- Vite使用esbuild来打包构建
- 使用go语言编写,可以直接转换成机器代码,无需经过字节码
- esbuild可以充分利用cpu的多内核,尽可能的让他们饱和运行
- esbuild所有内容都是从0开始编写,不依赖第三方,所以从一开始就考虑了各种性能问题。
Vite小结:
- Vite支持热更新(HMR) + 冷启动(没有像webpack一样在内存中打包bunding,而是启动了一个http服务器)
- Vite提供打包构建命令,按需进行打包
参考链接:https://pan.baidu.com/pfile/video