blog
blog copied to clipboard
rollup的使用说明
特别声明:如果你的工作内容是基于es2015(也就是es6),并且不需要代码分割,也不需要[模块热替换(HMR)][https://webpack.js.org/concepts/hot-module-replacement/],那么你可以很愉快的使用rollup进行开发了。否则,你可以绕行webpack了。
优势(与webpack相比)
- 代码的内容格式:编译运行出来的内容,人能看,并且能调试。如果你没办法理解我说的话,可以去看看webpack打包出来的代码
- 命令行的角度:比webpack更加的人性化,有什么问题或者警告都很详细的描述出来,并且准确的提供问题所在文件的位置,方便查找问题
- 如果是引入第三方的js,一旦import进来就会加载进入入口文件中,但如果不是第三方的js,要引入进来之后进行export操作或者执行,才会被解析到入口文件中
所用插件
- "babel-plugin-external-helpers": 这个模块是在.babelrc文件中体现,目的是让babel转义出来的帮助性代码只在该文件的头部出现一次,而不会再每个引入的模块中加入
- "babel-preset-latest": 这个模块也是在.babelrc文件中体现,目的是让babel转义的操作移至的最后,等rollup编译代码之后,否则会出错
- "rollup-plugin-babel": babel转义
- "rollup-plugin-node-resolve": 将import的代码的代码和自己写的代码打包打在一起
- "rollup-plugin-uglify": 压缩代码
比较好用的插件
- rollup-plugin-multi-entry 多入口
- rollup-plugin-multidest 多出口
- gulp-rollup-each 基于gulp的rollup转译的多入口到多出口
工具使用问题总结
- 当format改变为umd和iife的时候,如果你的入口文件中有export,那么就需要添加moduleName这个参数,为它产出的文件整体加个变量 问题解决地址:https://github.com/rollup/rollup/issues/1157
备注
rollup已经原生支持多入口多出口,可以查看英文文档
我在使用 rollup
的过程中遇到了如下问题,想请教下
'createElement' is not exported by node_modules/react/react.js
https://github.com/rollup/rollup/wiki/Troubleshooting#name-is-not-exported-by-module
在引用第三方库时,好像是因为库并没有严格的遵循 ES6 Module
输出模块,所以 import
的时候类似
import { routers, xxx } from 'react-router'
就会报上面的错误?查找了下解决方案,需要使用到 rollup-plugins-commonjs
的 namedExports
定义输出的模块名;可是这样的话会不会很麻烦呢,遇到有问题的情况就需要添加?还遇到过 moduleName
的问题
You must supply options.moduleName for IIFE bundles
不好意思,最近忙,今天才有时间看issue.
你可以看看这个:https://github.com/rollup/rollup/issues/1157 只要你有export,你就需要设置moduleName
你也可以看下我这个里面的关于rollup的demo,基本把大部分情况的使用都涉及到了。https://github.com/HuYuee/rollup-demo
hi. 在使用 rollup 通常有这种场景 比如我加入了 eslint 检验 js 是否符合规范 当我出现错误时。我修改了代码能否不在重新 启动 rollup 就可以重新编译
使用-w
@xierenyuan https://rollupjs.org/#npm-run-build
@HuYuee 恩后边 找到最根本的原因了 是rollup-watch 的bug rollup-watch 47 更新到v4.0就好呢0.0
@xierenyuan 哦了
你好,import进来的文件没有被babel转译是什么原因呢?
@hzxulin 是不是因为import进来的文件是node_modules里面的
@HuYuee 是自己编写的文件,不过我使用了gulp-rollup,因为本地还要运行一个页面,rollup的配置和你基本一样了,但是奇怪的是那些import的文件仍然没有被转译,这个import的文件在项目外不知道是不是会有影响
@hzxulin 入口文件被转译了吗?只有import的没有被转译?
@HuYuee 是的,入口文件被转译了,我找到问题了,引用项目外的js文件不会被转译,但是没办法解决这个问题- -能帮我一起找一下解决方案吗,加了babel中的include,没效果。
@HuYuee 解决了,但是是在项目的外面也放了package.json 然后安装对应的包, 就支持这个babel了。。
@hzxulin babel的机制就是这样。刚刚查到的。
Babel 会在正在被转录的文件的当前目录中查找一个 .babelrc 文件。 如果不存在,它会遍历目录树,直到找到一个 .babelrc 文件,或一个 package.json 文件中有 "babel": {} 。
@HuYuee 这个文件是存在的,只是在工作区内,引用工作区外的文件的时候,eslint,babel都会失效。在工作区外放置 .babelrc eslint配置文件,node_module文件就会使上述生效,但是污染工作区外的目录了。不知道有没有好办法解决这个问题
@hzxulin 可以在package.json里面配置
备注一下,rollup已经原生支持多入口多出口
@channg 有哪里有链接吗,为何我在官方文档没有看到这个方法的详细介绍或者例子
@three-ago-zhou
// rollup.config.js (building more than one bundle)
export default [{
input: 'main-a.js',
output: {
file: 'dist/bundle-a.js',
format: 'cjs'
}
}, {
input: 'main-b.js',
output: [
{
file: 'dist/bundle-b1.js',
format: 'cjs'
},
{
file: 'dist/bundle-b2.js',
format: 'esm'
}
]
}];
文档上就有,对了,看英文文档,中文文档没有
@channg thank you , 还是英文文档靠谱
@channg OK
你好, 能否请教下, 我用 rollup 打包如下文件
var commonFn = require("../common");
var nodeFn = Object.assign({}, commonFn);
module.exports = nodeFn;
它打包后的文件并没有将 require
的文件具体打包出来,打包输出如下:
var commonFn = require("../common");
var nodeFn = Object.assign({}, commonFn);
module.exports = nodeFn;
这是我的配置, 使用 rollup -c script/rollup.config.js
命令行进行打包:
export default [{
input: path.resolve(rootPath, 'dist/src/node', 'index.js'),
output: {
file: `lib/${pkg.name}.back.js`,
format: 'cjs'
},
}]
请问如何将 require
的文件也打包出来呢, 是少了什么插件之类的么?
@MuYunyun 试下这个插件“rollup-plugin-node-resolve”
使用 rollup-plugin-commonjs 这个插件解决了我的问题
@hzxulin babel的机制就是这样。刚刚查到的。
Babel 会在正在被转录的文件的当前目录中查找一个 .babelrc 文件。 如果不存在,它会遍历目录树,直到找到一个 .babelrc 文件,或一个 package.json 文件中有 "babel": {} 。
你好我引入的是node_modules/下的antd/es,但是被转成了commonjs
你好我咨询个问题
$ node scripts/build.js
dirs [ 'reactivity', 'shared' ]
build fn reactivity
build fn shared
loaded rollup.config.js with warnings
(!) Unused external imports
default imported from external module "rollup-plugin-polyfill-node" but never used in "rollup.config.js"
loaded rollup.config.js with warnings
(!) Unused external imports
default imported from external module "rollup-plugin-polyfill-node" but never used in "rollup.config.js"
options { name: 'VueReactivity', formats: [ 'es-bunlder', 'cjs', 'global' ] }
_output {
file: 'D:\\DemoStyle\\ts\\javascript-test\\mini-vue3\\packages\\reactivity\\dist\\reactivity.esm-bunlder.js',
format: 'es',
name: 'VueReactivity',
sourcemap: true
}
format es-bunlder
options { name: 'VueShared', formats: [ 'es-bunlder', 'cjs', 'global' ] }
_output {
file: 'D:\\DemoStyle\\ts\\javascript-test\\mini-vue3\\packages\\shared\\dist\\shared.esm-bunlder.js',
format: 'es',
name: 'VueShared',
sourcemap: true
}
format es-bunlder
_output {
file: 'D:\\DemoStyle\\ts\\javascript-test\\mini-vue3\\packages\\reactivity\\dist\\reactivity.cjs.js',
format: 'cjs',
name: 'VueReactivity',
sourcemap: true
}
format cjs
_output {
file: 'D:\\DemoStyle\\ts\\javascript-test\\mini-vue3\\packages\\reactivity\\dist\\reactivity.global.js',
format: 'iife',
name: 'VueReactivity',
sourcemap: true
}
format global
(!) You have passed an unrecognized option
Unknown input options: moduleName, plugin. Allowed options: acorn, acornInjectPlugins, cache, context, experimentalCacheExpiry, external, inlineDynamicImports, input, makeAbsoluteExternalsRelative, manualChunks, maxParallelFileReads, moduleContext, onwarn, perf, plugins, preserveEntrySignatures, preserveModules, preserveSymlinks, shimMissingExports, strictDeprecations, treeshake, watch
(!) You have passed an unrecognized option
Unknown input options: moduleName, plugin. Allowed options: acorn, acornInjectPlugins, cache, context, experimentalCacheExpiry, external, inlineDynamicImports, input, makeAbsoluteExternalsRelative, manualChunks, maxParallelFileReads, moduleContext, onwarn, perf, plugins, preserveEntrySignatures, preserveModules, preserveSymlinks, shimMissingExports, strictDeprecations, treeshake, watch
(!) You have passed an unrecognized option
Unknown input options: moduleName, plugin. Allowed options: acorn, acornInjectPlugins, cache, context, experimentalCacheExpiry, external, inlineDynamicImports, input, makeAbsoluteExternalsRelative, manualChunks, maxParallelFileReads, moduleContext, onwarn, perf, plugins, preserveEntrySignatures, preserveModules, preserveSymlinks, shimMissingExports, strictDeprecations, treeshake, watch
D:\DemoStyle\ts\javascript-test\mini-vue3\packages\reactivity\src\index.ts → packages\reactivity\dist\reactivity.esm-bunlder.js...
(node:7200) [DEP0148] DeprecationWarning: Use of deprecated folder mapping "./" in the "exports" field module resolution of the package at D:\DemoStyle\ts\javascript-test\mini-vue3\node_modules\rollup-plugin-typescript2\node_modules\tslib\package.json.
Update this package.json to use a subpath pattern like "./*".
(Use `node --trace-deprecation ...` to show where the warning was created)
_output {
file: 'D:\\DemoStyle\\ts\\javascript-test\\mini-vue3\\packages\\shared\\dist\\shared.cjs.js',
format: 'cjs',
name: 'VueShared',
sourcemap: true
}
format cjs
_output {
file: 'D:\\DemoStyle\\ts\\javascript-test\\mini-vue3\\packages\\shared\\dist\\shared.global.js',
format: 'iife',
name: 'VueShared',
sourcemap: true
}
[!] Error: Could not resolve './reactive' from packages\reactivity\src\index.ts
format global
(!) You have passed an unrecognized option
Unknown input options: moduleName, plugin. Allowed options: acorn, acornInjectPlugins, cache, context, experimentalCacheExpiry, external, inlineDynamicImports, input, makeAbsoluteExternalsRelative, manualChunks, maxParallelFileReads, moduleContext, onwarn, perf, plugins, preserveEntrySignatures, preserveModules, preserveSymlinks, shimMissingExports, strictDeprecations, treeshake, watch
(!) You have passed an unrecognized option
Unknown input options: moduleName, plugin. Allowed options: acorn, acornInjectPlugins, cache, context, experimentalCacheExpiry, external, inlineDynamicImports, input, makeAbsoluteExternalsRelative, manualChunks, maxParallelFileReads, moduleContext, onwarn, perf, plugins, preserveEntrySignatures, preserveModules, preserveSymlinks, shimMissingExports, strictDeprecations, treeshake, watch
(!) You have passed an unrecognized option
Unknown input options: moduleName, plugin. Allowed options: acorn, acornInjectPlugins, cache, context, experimentalCacheExpiry, external, inlineDynamicImports, input, makeAbsoluteExternalsRelative, manualChunks, maxParallelFileReads, moduleContext, onwarn, perf, plugins, preserveEntrySignatures, preserveModules, preserveSymlinks, shimMissingExports, strictDeprecations, treeshake, watch
Error: Could not resolve './reactive' from packages\reactivity\src\index.ts
at error (D:\DemoStyle\ts\javascript-test\mini-vue3\node_modules\rollup\dist\shared\rollup.js:158:30)
at ModuleLoader.handleResolveId (D:\DemoStyle\ts\javascript-test\mini-vue3\node_modules\rollup\dist\shared\rollup.js:22263:24)
at D:\DemoStyle\ts\javascript-test\mini-vue3\node_modules\rollup\dist\shared\rollup.js:22257:26
D:\DemoStyle\ts\javascript-test\mini-vue3\packages\shared\src\index.ts → packages\shared\dist\shared.esm-bunlder.js...
(node:24440) [DEP0148] DeprecationWarning: Use of deprecated folder mapping "./" in the "exports" field module resolution of the package at D:\DemoStyle\ts\javascript-test\mini-vue3\node_modules\rollup-plugin-typescript2\node_modules\tslib\package.json.
Update this package.json to use a subpath pattern like "./*".
(Use `node --trace-deprecation ...` to show where the warning was created)
[!] Error: Could not resolve './makeMap' from packages\shared\src\index.ts
Error: Could not resolve './makeMap' from packages\shared\src\index.ts
at error (D:\DemoStyle\ts\javascript-test\mini-vue3\node_modules\rollup\dist\shared\rollup.js:158:30)
at ModuleLoader.handleResolveId (D:\DemoStyle\ts\javascript-test\mini-vue3\node_modules\rollup\dist\shared\rollup.js:22263:24)
at D:\DemoStyle\ts\javascript-test\mini-vue3\node_modules\rollup\dist\shared\rollup.js:22257:26
失败 Error: Command failed with exit code 1: rollup -c --environment TARGET:reactivity
at makeError (D:\DemoStyle\ts\javascript-test\mini-vue3\node_modules\execa\lib\error.js:60:11)
at handlePromise (D:\DemoStyle\ts\javascript-test\mini-vue3\node_modules\execa\index.js:118:26)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async build (D:\DemoStyle\ts\javascript-test\mini-vue3\scripts\build.js:22:3)
at async Promise.all (index 0) {
shortMessage: 'Command failed with exit code 1: rollup -c --environment TARGET:reactivity',
command: 'rollup -c --environment TARGET:reactivity',
escapedCommand: 'rollup -c --environment "TARGET:reactivity"',
exitCode: 1,
signal: undefined,
signalDescription: undefined,
stdout: undefined,
stderr: undefined,
failed: true,
timedOut: false,
isCanceled: false,
killed: false
}
// 通过 rollup进行 打包
// 1.引入相关依赖
import path from "path"; // 处理路径
import ts from "rollup-plugin-typescript2";// 解析ts
import json from "@rollup/plugin-json"; // 解析json
import resolvePlugin from "@rollup/plugin-node-resolve";// 解析 第三方插件
import CommonJS from "@rollup/plugin-commonjs";
import polyfillNode from "rollup-plugin-polyfill-node"
import babel from "@rollup/plugin-babel"
// 2.获取打包的文件路径
const packagesDir = path.resolve(__dirname, 'packages');
// 2.1获取需要打包的包
const packageDir = path.resolve(packagesDir, process.env.TARGET)
// 2.2 获取每个包的项目配置
let resolve = p => path.resolve(packageDir, p);
const pkg = require(resolve('package.json'));// 获取项目配置
const packageOptions = pkg.buildOptions || {}
// 获取包名
const name = path.basename(packageDir) || packageOptions.filename;
// 3 创建一个
const outputConfig = {
'es-bunlder': {
file: resolve(`dist/${name}.esm-bunlder.js`),
format: 'es',
},
'esm-browser': {
file: resolve(`dist/${name}.esm-browser.js`),
format: `es`
},
'cjs': {
file: resolve(`dist/${name}.cjs.js`),
format: 'cjs'
},
'global': {
file: resolve(`dist/${name}.global.js`),
format: 'iife'
},
'esm-bundler-runtime': {
file: resolve(`dist/${name}.runtime.esm-bundler.js`),
format: `es`
},
'esm-browser-runtime': {
file: resolve(`dist/${name}.runtime.esm-browser.js`),
format: 'es'
},
'global-runtime': {
file: resolve(`dist/${name}.runtime.global.js`),
format: 'iife'
}
};
const options = pkg.buildOptions;
console.log("options", options);
// rollup需要导出配置
function createConfig(format, output) {
// 进行打包
let _output = {
...output,
name: options.name,
sourcemap: true,
}
console.log("_output", _output)
console.log("format", format)
// 生成 rollup 配置
return {
input: resolve('src/index.ts'),
output: _output,
moduleName: options.name,
plugin: [
json(),
ts({
tsconfig: path.resolve(__dirname, "tsconfig.json"),
}),
resolvePlugin(),
CommonJS(),
babel({
exclude: 'node_modules/**',
})
]
}
}
export default options.formats.map(format => createConfig(format, outputConfig[format]));
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Projects */
// "incremental": true, /* Enable incremental compilation */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "esnext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
// "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
/* Modules */
"module": "ESnext", /* Specify what module code is generated. */
// "rootDir": "./", /* Specify the root folder within your source files. */
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
"baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
"resolveJsonModule": true, /* Enable importing .json files */
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
"sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
"outDir": "./", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
"allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": false, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
// "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true,
"paths": {
"@vue/*":["packages/*"]
} /* Skip type checking all .d.ts files. */
}
}
这个是我的配置 我打包之后就报这个错请问一下是我配置哪个地方出问题了么?
请教下 如果是多出口情况下,插件加载逻辑是什么。类似:
{
input: 'src/index.ts',
output: [
{
dir: 'dist/es',
format: 'es',
plugins: [
pluginA, pluginB
]
},
{
dir: 'dist/cjs',
format: 'cjs',
plugins: [
pluginC
]
},
],
plugins: [
pluginD
]
}
对应到每个输出,外面的plugin还会混合到每个子output加载嘛