手动打包
Rollup
提供了可在 Node.js
中使用的 JavaScript API
。一般情况下不需要使用它,而应使用命令行 API
,除非你要扩展 Rollup
本身或者使用它进行一些高级操作,比如通过编程生成 bundle
。 下面为大家展示如何以编程的方式生成bundle
。
构建
src/index.ts
import "./index.scss";
import $ from "jquery";
import { getName } from "util/index";
import { getName1 } from "util/index1";
import cloneDeep from "lodash/cloneDeep";
import underscore from "underscore";
const test = () => {
return process.env.NODE_ENV;
};
const envStr = test();
console.log(envStr);
const nameStr = getName();
console.log(nameStr);
const nameStr1 = getName1();
console.log(nameStr1);
const promiseFunc = () => {
return new Promise((resolve, reject) => {
resolve(100);
});
};
const asyncFunc = async () => {
const result = await promiseFunc();
console.log(result);
};
asyncFunc();
const data = {
name: "dataName",
};
const dataCopy = cloneDeep(data);
dataCopy.name = "dataCopyName";
console.log(data);
console.log(dataCopy);
const dataCopy1 = underscore.clone(data);
dataCopy1.name = "dataCopy1Name";
console.log(data);
console.log(dataCopy1);
console.log($(".box"));
package.json
{
"name": "auto",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"build": "node scripts/build.js"
},
"devDependencies": {
"@babel/core": "^7.21.0",
"@babel/preset-env": "^7.20.2",
"@babel/preset-typescript": "^7.21.0",
"@rollup/plugin-alias": "^4.0.3",
"@rollup/plugin-babel": "^6.0.3",
"@rollup/plugin-commonjs": "^24.0.1",
"@rollup/plugin-html": "^1.0.2",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-replace": "^5.0.2",
"@rollup/plugin-terser": "^0.4.0",
"@rollup/plugin-typescript": "^11.0.0",
"@types/node": "^18.14.6",
"babel-plugin-lodash": "^3.3.4",
"node-sass": "^8.0.0",
"postcss": "^8.4.21",
"rollup": "^3.18.0",
"rollup-plugin-livereload": "^2.0.5",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-serve": "^2.0.2",
"sass": "^1.58.3",
"tslib": "^2.5.0",
"typescript": "^4.9.5"
},
"dependencies": {
"@types/jquery": "^3.5.16",
"@types/lodash": "^4.14.191",
"@types/underscore": "^1.11.4",
"jquery": "^3.6.3",
"lodash": "^4.17.21",
"underscore": "^1.13.6"
}
}
tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"outDir": "dist",
"strict": true,
"newLine": "LF",
"allowJs": true,
"types": ["node"],
"jsx": "preserve",
"target": "es2015",
"module": "ESNext",
"skipLibCheck": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"lib": ["es2015", "esnext", "dom"],
"forceConsistentCasingInFileNames": true,
"paths": {
"util/*": ["src/util/*"],
}
},
"include": ["src/*"],
"exclude": ["node_modules", "dist"],
}
babel.config.js
const presets = [
[
"@babel/preset-env",
{
modules: false,
},
],
"@babel/preset-typescript",
];
const plugins = [["lodash"]];
module.exports = {
presets,
plugins,
};
scripts/build.js
const rollup = require("rollup");
const rollupOptions = require("./config");
const inputOptions = { ...rollupOptions };
const outputOptions = { ...rollupOptions.output };
const watchOptions = {
...inputOptions,
output: [outputOptions],
};
async function build() {
const bundle = await rollup.rollup(inputOptions);
await bundle.write(outputOptions);
rollup.watch(watchOptions);
}
build();
scripts/config.js
const path = require("path");
const RollupPluginHtml = require("@rollup/plugin-html");
const RollupPluginJson = require("@rollup/plugin-json");
const RollupPluginServe = require("rollup-plugin-serve");
const RollupPluginAlias = require("@rollup/plugin-alias");
const RollupPluginBabel = require("@rollup/plugin-babel");
const RollupPluginTerser = require("@rollup/plugin-terser");
const RollupPluginPostcss = require("rollup-plugin-postcss");
const RollupPluginReplace = require("@rollup/plugin-replace");
const RollupPluginCommonjs = require("@rollup/plugin-commonjs");
const RollupPluginLiverLoad = require("rollup-plugin-livereload");
const RollupPluginTypescript = require("@rollup/plugin-typescript");
const RollupPluginNodeResolve = require("@rollup/plugin-node-resolve");
const resolve = (p) => {
return path.resolve(__dirname, "../", p);
};
const version = require("../package.json").version;
const extensions = {
babel: [".ts", ".js"],
common: [".ts", ".tsx", ".js", ".jsx", ".json", ".css", ".sass", ".scss"],
};
const customResolver = RollupPluginNodeResolve({
extensions: extensions.common,
});
const customHtmlTemplate = async ({
attributes,
files,
meta,
publicPath,
title,
}) => {
const scripts = (files.js || [])
.map(({ fileName }) => {
const attrs = RollupPluginHtml.makeHtmlAttributes(attributes.script);
return `<script src="${publicPath}${fileName}"${attrs}></script>`;
})
.join("\n");
const links = (files.css || [])
.map(({ fileName }) => {
const attrs = RollupPluginHtml.makeHtmlAttributes(attributes.link);
return `<link href="${publicPath}${fileName}" rel="stylesheet"${attrs}>`;
})
.join("\n");
const metas = meta
.map((input) => {
const attrs = RollupPluginHtml.makeHtmlAttributes(input);
return `<meta${attrs}>`;
})
.join("\n");
return `
<!doctype html>
<html${RollupPluginHtml.makeHtmlAttributes(attributes.html)}>
<head>
${metas}
<title>${title}</title>
${links}
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/underscore.js/1.13.6/underscore-umd.min.js"></script>
</head>
<body>
${scripts}
</body>
</html>`;
};
const rollupPlugins = [
RollupPluginJson(),
RollupPluginAlias({
entries: [
{ find: "util", replacement: resolve("src/util") },
],
customResolver,
}),
RollupPluginBabel.babel({
babelHelpers: "bundled",
exclude: ["node_modules/**"],
extensions: extensions.babel,
}),
RollupPluginCommonjs(),
RollupPluginNodeResolve.nodeResolve({
extensions: extensions.common,
}),
RollupPluginTypescript({
tsconfig: resolve("tsconfig.json"),
cacheDir: ".rollup.tscache",
}),
RollupPluginReplace({
___VERSION__: version,
preventAssignment: true,
__DEV__: process.env.NODE_ENV === "development",
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
}),
RollupPluginTerser({
maxWorkers: 4,
}),
RollupPluginServe({
open: true,
port: 4000,
contentBase: ["dist"],
}),
RollupPluginLiverLoad({
watch: "dist",
}),
RollupPluginPostcss(),
RollupPluginHtml({
fileName: "index.html",
title: "Rollup 通用开发环境",
template: customHtmlTemplate,
}),
];
module.exports = {
cache: true,
watch: {
include: "src/**",
exclude: "node_modules/**"
},
input: resolve("src/index.ts"),
output: {
file: path.resolve("dist/index.js"),
format: "umd",
banner: `/** Rollup 通用开发环境 版本 v${version} **/`,
name: "RollupName",
exports: "auto",
globals: {
jquery: "$",
underscore: "_",
},
},
plugins: rollupPlugins,
external: ["jquery", "underscore"],
};
命令行
-
初始化项目: 通过
yarn init -y
初始化项目 -
配置命令行: 通过
package.json - scripts
配置命令行 -
配置
rollup
命令行
"scripts": {
"build": "rollup --watch --config rollup.config.js --environment NODE_ENV:development"
}
替换变量
Rollup
通过 @rollup/plugin-replace
构建产物时替换变量
相关代码
const RollupPluginReplace = require("@rollup/plugin-replace");
RollupPluginReplace({
___VERSION__: version,
preventAssignment: true,
__DEV__: process.env.NODE_ENV === "development",
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
})
压缩产物
通过@rollup/plugin-terser
压缩构建产物
相关代码
const RollupPluginTerser = require("@rollup/plugin-terser");
RollupPluginTerser({
maxWorkers: 4,
})
支持 Css
通过rollup-plugin-postcss
来支持引入.css
、.scss
、.less
等样式文件
相关代码
const RollupPluginPostcss = require("rollup-plugin-postcss");
RollupPluginPostcss()
支持 CDN
-
通过
external
将模块保留在bundle
外部(忽略打包)external: ["jquery", "underscore"]
-
通过
output.globals
注册外部依赖的全局变量:外部依赖 : 全局变量
中, 外部依赖是所引入的依赖包名, 全局变量是该依赖的CDN
文件挂载在window
上的属性名。external: ["jquery", "underscore"],
output: {
globals: {
jquery: "$",
underscore: "_",
}
} -
通过
output.format
指定生成的bundle
格式: 如果需要在html
等浏览器用到外部的依赖,需要使用umd
或者iife
的格式output: {
format: "iife",
} -
index.html
模版中引入外部依赖的CDN
地址<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/underscore.js/1.13.6/underscore-umd.min.js"></script>
支持 Alias
Rollup
通过@rollup/plugin-alias
和@rollup/plugin-node-resolve
来支持路径别名
const RollupPluginAlias = require("@rollup/plugin-alias");
const RollupPluginNodeResolve = require("@rollup/plugin-node-resolve");
const customResolver = RollupPluginNodeResolve({
extensions: extensions.common,
});
RollupPluginAlias({
entries: [
{ find: "util", replacement: path.resolve(__dirname, "src", "util") },
],
customResolver,
})
支持 HTML
Rollup
通过@rollup/plugin-html
来自动生成HTML
模版
相关代码
const RollupPluginHtml = require("@rollup/plugin-html");
const customHtmlTemplate = async ({
attributes,
files,
meta,
publicPath,
title
}) => {
const scripts = (files.js || [])
.map(({ fileName }) => {
const attrs = RollupPluginHtml.makeHtmlAttributes(attributes.script);
return `<script src="${publicPath}${fileName}"${attrs}></script>`;
})
.join('\n');
const links = (files.css || [])
.map(({ fileName }) => {
const attrs = RollupPluginHtml.makeHtmlAttributes(attributes.link);
return `<link href="${publicPath}${fileName}" rel="stylesheet"${attrs}>`;
})
.join('\n');
const metas = meta
.map((input) => {
const attrs = RollupPluginHtml.makeHtmlAttributes(input);
return `<meta${attrs}>`;
})
.join('\n');
return `
<!doctype html>
<html${ RollupPluginHtml.makeHtmlAttributes(attributes.html)}>
<head>
${metas}
<title>${title}</title>
${links}
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/underscore.js/1.13.6/underscore-umd.min.js"></script>
</head>
<body>
${scripts}
</body>
</html>`;
};
RollupPluginHtml({
fileName: "index.html",
title: "Rollup 通用开发环境",
template: customHtmlTemplate
})
支持 Babel
为了能够使用浏览器和 Node.js
尚不支持的最新 JavaScript
特性,许多开发人员会在项目中使用 Babel
。需要安装以下依赖:
-
@babel/core
-
@babel/preset-env
-
babel-plugin-lodash
-
@rollup/plugin-babel
-
@babel/preset-typescript
-
安装相关依赖
yarn add @babel/core @babel/preset-env babel-plugin-lodash @rollup/plugin-babel @babel/preset-typescript -D
-
配置
babel
const presets = [
[
"@babel/preset-env",
{
modules: false,
},
],
"@babel/preset-typescript",
];
const plugins = [["lodash"]];
module.exports = {
presets,
plugins,
}; -
配置
rollup.plugins
const RollupPluginBabel = require("@rollup/plugin-babel");
RollupPluginBabel.babel({
babelHelpers: "bundled",
exclude: ["node_modules/**"],
extensions: extensions.babel,
})
支持 Server
通过rollup-plugin-serve
开启本地化服务
相关代码
const RollupPluginServe = require("rollup-plugin-serve");
RollupPluginServe({
open: true,
port: 4000,
contentBase: ["dist"],
})
支持 TypeScript
为了能够使用浏览器和 Node.js
使用TypeScript
特性,需要安装以下依赖:
-
tslib
-
typescript
-
@types/node
-
@rollup/plugin-typescript
-
Typescript
初始化: 根目录执行tsc --init
, 生成tsconfig.json
-
TypeScript
相关配置: 配置如下{
"compilerOptions": {
"baseUrl": ".",
"outDir": "dist",
"strict": true,
"newLine": "LF",
"allowJs": true,
"types": ["node"],
"jsx": "preserve",
"target": "es2015",
"module": "ESNext",
"skipLibCheck": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"lib": ["es2015", "esnext", "dom"],
"forceConsistentCasingInFileNames": true,
"paths": {
"util/*": ["src/util/*"],
}
},
"include": ["src/*"],
"exclude": ["node_modules", "dist"],
}-
compilerOptions.baseUrl
: 项目基础路径 -
compilerOptions.outDir
: -
compilerOptions.paths
: 用于配置路径别名, 该配置项需要指定baseUrl
-
-
rollup
配置Typescript
插件const RollupPluginTypescript = require("@rollup/plugin-typescript");
RollupPluginTypescript({
tsconfig: path.resolve(__dirname, "tsconfig.json"),
cacheDir: ".rollup.tscache",
})
支持 Livereload
rollup
通过 rollup-plugin-livereload
来支持本地开发环境的热更新
相关代码
const RollupPluginLiverLoad = require("rollup-plugin-livereload");
RollupPluginLiverLoad({
watch: 'dist',
})
支持 Json Import
rollup
通过 @rollup/plugin-json
来支JSON
文件的引入
相关代码
const RollupPluginJson = require("@rollup/plugin-json");
RollupPluginJson()
支持 EsModule Import
rollup
通过 @rollup/plugin-node-resolve
来支EsModule
引入方式
相关代码
const RollupPluginNodeResolve = require("@rollup/plugin-node-resolve");
RollupPluginNodeResolve.nodeResolve({
extensions: extensions.common,
})
支持 CommonJs Import
rollup
通过 @rollup/plugin-commonjs
来支CommonJs
引入方式
相关代码
const RollupPluginCommonjs = require("@rollup/plugin-commonjs");
RollupPluginCommonjs()