diff --git a/CHANGELOG.md b/CHANGELOG.md index c853daac87a..9ed5e45e2ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,67 @@ # rollup changelog +## 1.0.0 +*unreleased* + +### Breaking Changes +* Several (mostly deprecated) options have been removed or renamed (#2293, #2409): + - banner -> output.banner + - dest -> output.file + - entry -> input + - experimentalCodeSplitting -> now always active + - experimentalDynamicImport -> now always active + - experimentalPreserveModules -> preserveModules + - exports -> output.exports + - extend -> output.extend + - footer -> output.footer + - format -> output.format + - freeze -> output.freeze + - globals -> output.globals + - indent -> output.indent + - interop -> output.interop + - intro -> output.intro + - load -> use plugin API + - moduleName -> output.name + - name -> output.name + - noConflict -> output.noConflict + - output.moduleId -> output.amd.id + - outro -> output.outro + - paths -> output.paths + - preferConst -> output.preferConst + - pureExternalModules -> treeshake.pureExternalModules + - resolveExternal -> use plugin API + - resolveId -> use plugin API + - sourcemap -> output.sourcemap + - sourceMap -> output.sourcemap + - sourceMapFile -> output.sourcemapFile + - strict -> output.strict + - targets -> use output as an array + - transform -> use plugin API + - useStrict -> output.strict +* In general, output options can no longer be used as input options (#2409) +* `bundle.generate` and `bundle.write` now return a new format (#2293) +* Several plugin hooks have become deprecated and will display warnings when used (#2409): + - transformBundle + - transformChunk + - ongenerate + - onwrite +* Plugin transform dependencies are deprecated in favour of the `watchChange` plugin hook (#2409) +* Accessing `this.watcher` in plugin hooks is deprecated in favour of the `watchChange` plugin hook (#2409) +* Using dynamic import statements will by default create a new chunk unless `inlineDynamicImports` is used (#2293) +* Rollup now uses acorn@6 which means that acorn plugins must be compatible with this version; acorn is now external for non-browser builds to make plugins work (#2293) + +### Features +* The `--dir` ClI option can now be aliased as `-d` (#2293) +* The `--input` option now supports named entry points via `=` (#2293) + +### Bug Fixes +* Both the `--input` option as well as the default CLI option now support named inputs (#2293) + +### Pull Requests +* [#2293](https://github.com/rollup/rollup/pull/2293): Unify code paths for 1.0 relase and update documentation (@guybedford and @lukastaegert) +* [#2409](https://github.com/rollup/rollup/pull/2409): Remove old deprecated features and add new deprecation warnings (@guybedford) +* [#2486](https://github.com/rollup/rollup/pull/2486): Upgrade to acorn 6 (@marijnh) + ## 0.68.2 *2018-12-23* diff --git a/bin/src/help.md b/bin/src/help.md index 803c1fe3927..00680670cf1 100644 --- a/bin/src/help.md +++ b/bin/src/help.md @@ -5,32 +5,51 @@ Usage: rollup [options] Basic options: --v, --version Show version number --h, --help Show this help message -c, --config Use this config file (if argument is used but value is unspecified, defaults to rollup.config.js) --w, --watch Watch files in bundle and rebuild on changes --i, --input Input (alternative to ) --o, --file Output (if absent, prints to stdout) --f, --format [es] Type of output (amd, cjs, es, iife, umd) +-d, --dir Directory for chunks (if absent, prints to stdout) -e, --external Comma-separate list of module IDs to exclude --g, --globals Comma-separate list of `module ID:Global` pairs - Any module IDs defined here are added to external --n, --name Name for UMD export +-f, --format Type of output (amd, cjs, esm, iife, umd) +-g, --globals Comma-separate list of `moduleID:Global` pairs +-h, --help Show this help message +-i, --input Input (alternative to ) -m, --sourcemap Generate sourcemap (`-m inline` for inline map) ---amd.id ID for AMD module (default is anonymous) ---amd.define Function to use in place of `define` ---no-strict Don't emit a `"use strict";` in the generated modules. ---no-indent Don't indent result +-n, --name Name for UMD export +-o, --file Single output file (if absent, prints to stdout) +-v, --version Show version number +-w, --watch Watch files in bundle and rebuild on changes +--amd.id ID for AMD module (default is anonymous) +--amd.define Function to use in place of `define` +--assetFileNames Name pattern for emitted assets +--banner Code to insert at top of bundle (outside wrapper) +--chunkFileNames Name pattern for emitted secondary chunks +--compact Minify wrapper code +--context Specify top-level `this` value +--entryFileNames Name pattern for emitted entry chunks --environment Settings passed to config file (see example) ---no-conflict Generate a noConflict method for UMD globals ---no-treeshake Disable tree-shaking ---silent Don't print warnings ---intro Content to insert at top of bundle (inside wrapper) ---outro Content to insert at end of bundle (inside wrapper) ---banner Content to insert at top of bundle (outside wrapper) ---footer Content to insert at end of bundle (outside wrapper) +--no-esModule Do not add __esModule property +--exports Specify export mode (auto, default, named, none) +--extend Extend global variable defined by --name +--footer Code to insert at end of bundle (outside wrapper) +--no-freeze Do not freeze namespace objects +--no-indent Don't indent result --no-interop Do not include interop block +--inlineDynamicImports Create single bundle when using dynamic imports +--intro Code to insert at top of bundle (inside wrapper) +--namespaceToStringTag Create proper `.toString` methods for namespaces +--noConflict Generate a noConflict method for UMD globals +--no-strict Don't emit `"use strict";` in the generated modules +--outro Code to insert at end of bundle (inside wrapper) +--preferConst Use `const` instead of `var` for exports +--preserveModules Preserve module structure +--preserveSymlinks Do not follow symlinks when resolving files +--shimMissingExports Create shim variables for missing exports +--silent Don't print warnings +--sourcemapExcludeSources Do not include source code in source maps +--sourcemapFile Specify bundle position for source maps +--no-treeshake Disable tree-shaking optimisations +--no-treeshake.propertyReadSideEffects Ignore property access side-effects +--treeshake.pureExternalModules Assume side-effect free externals Examples: diff --git a/bin/src/run/batchWarnings.ts b/bin/src/run/batchWarnings.ts index 98f9c91d350..41a2e88437a 100644 --- a/bin/src/run/batchWarnings.ts +++ b/bin/src/run/batchWarnings.ts @@ -55,7 +55,7 @@ export default function batchWarnings() { handler.fn(warnings); } else { warnings.forEach(warning => { - stderr(`${tc.bold.yellow('(!)')} ${tc.bold.yellow(warning.message)}`); + title(warning.message); if (warning.url) info(warning.url); @@ -87,14 +87,6 @@ const immediateHandlers: { stderr(warning.message); }, - DEPRECATED_OPTIONS: warning => { - title(`Some options have been renamed`); - info(`https://gist.github.com/Rich-Harris/d472c50732dab03efeb37472b08a3f32`); - warning.deprecations.forEach(option => { - stderr(`${tc.bold(option.old)} is now ${option.new}`); - }); - }, - MISSING_NODE_BUILTINS: warning => { title(`Missing shims for Node.js built-ins`); @@ -103,7 +95,7 @@ const immediateHandlers: { ? `'${warning.modules[0]}'` : `${warning.modules .slice(0, -1) - .map(name => `'${name}'`) + .map((name: string) => `'${name}'`) .join(', ')} and '${warning.modules.slice(-1)}'`; stderr( `Creating a browser bundle that depends on ${detail}. You might need to include https://www.npmjs.com/package/rollup-plugin-node-builtins` @@ -263,11 +255,13 @@ const deferredHandlers: { items.forEach(warning => { if (warning.url !== lastUrl) info((lastUrl = warning.url)); - const loc = warning.loc - ? `${relativeId(warning.id)}: (${warning.loc.line}:${warning.loc.column})` - : relativeId(warning.id); - - stderr(tc.bold(relativeId(loc))); + if (warning.id) { + let loc = relativeId(warning.id); + if (warning.loc) { + loc += `: (${warning.loc.line}:${warning.loc.column})`; + } + stderr(tc.bold(loc)); + } if (warning.frame) info(warning.frame); }); }); diff --git a/bin/src/run/build.ts b/bin/src/run/build.ts index 339e1734354..2c3985199f2 100644 --- a/bin/src/run/build.ts +++ b/bin/src/run/build.ts @@ -3,9 +3,10 @@ import * as rollup from 'rollup'; import tc from 'turbocolor'; import { InputOptions, + OutputAsset, + OutputChunk, OutputOptions, - RollupBuild, - RollupSingleFileBuild + RollupBuild } from '../../../src/rollup/types'; import relativeId from '../../../src/utils/relativeId'; import { handleError, stderr } from '../logging'; @@ -19,12 +20,7 @@ export default function build( warnings: BatchWarnings, silent = false ) { - const useStdout = - outputOptions.length === 1 && - !outputOptions[0].file && - !outputOptions[0].dir && - inputOptions.input instanceof Array === false && - typeof inputOptions.input !== 'object'; + const useStdout = !outputOptions[0].file && !outputOptions[0].dir; const start = Date.now(); const files = useStdout ? ['stdout'] : outputOptions.map(t => relativeId(t.file || t.dir)); @@ -44,7 +40,7 @@ export default function build( return rollup .rollup(inputOptions) - .then((bundle: RollupSingleFileBuild | RollupBuild) => { + .then((bundle: RollupBuild) => { if (useStdout) { const output = outputOptions[0]; if (output.sourcemap && output.sourcemap !== 'inline') { @@ -54,13 +50,21 @@ export default function build( }); } - return (bundle).generate(output).then(({ code, map }) => { - if (!code) return; - if (output.sourcemap === 'inline') { - code += `\n//# ${SOURCEMAPPING_URL}=${map.toUrl()}\n`; + return bundle.generate(output).then(({ output: outputs }) => { + for (const file of outputs) { + let source: string | Buffer; + if ((file).isAsset) { + source = (file).source; + } else { + source = (file).code; + if (output.sourcemap === 'inline') { + source += `\n//# ${SOURCEMAPPING_URL}=${(file).map.toUrl()}\n`; + } + } + if (outputs.length > 1) + process.stdout.write('\n' + tc.cyan(tc.bold('//→ ' + file.fileName + ':')) + '\n'); + process.stdout.write(source); } - - process.stdout.write(code); }); } @@ -68,7 +72,7 @@ export default function build( () => bundle ); }) - .then((bundle?: RollupSingleFileBuild | RollupBuild) => { + .then((bundle?: RollupBuild) => { warnings.flush(); if (!silent) stderr( diff --git a/bin/src/run/index.ts b/bin/src/run/index.ts index 872a434ceaa..ba44423deea 100644 --- a/bin/src/run/index.ts +++ b/bin/src/run/index.ts @@ -10,34 +10,34 @@ import loadConfigFile from './loadConfigFile'; import watch from './watch'; export default function runRollup(command: any) { - if (command._.length >= 1) { + let inputSource; + if (command._.length > 0) { if (command.input) { handleError({ code: 'DUPLICATE_IMPORT_OPTIONS', message: 'use --input, or pass input path as argument' }); } + inputSource = command._; + } else if (typeof command.input === 'string') { + inputSource = [command.input]; + } else { + inputSource = command.input; } - if (command.dir) { - if (command._.length) { - if (command._.some((input: string) => input.indexOf('=') !== -1)) { - command.input = {}; - command._.forEach((input: string) => { - const equalsIndex = input.indexOf('='); - const value = input.substr(equalsIndex + 1); - let key = input.substr(0, equalsIndex); - if (!key) key = getAliasName(input); - command.input[key] = value; - }); - } else { - command.input = command._; - } - } else if (typeof command.input === 'string') { - command.input = [command.input]; + if (inputSource && inputSource.length > 0) { + if (inputSource.some((input: string) => input.indexOf('=') !== -1)) { + command.input = {}; + inputSource.forEach((input: string) => { + const equalsIndex = input.indexOf('='); + const value = input.substr(equalsIndex + 1); + let key = input.substr(0, equalsIndex); + if (!key) key = getAliasName(input); + command.input[key] = value; + }); + } else { + command.input = inputSource; } - } else if (command._.length === 1) { - command.input = command._[0]; } if (command.environment) { @@ -101,22 +101,12 @@ function execute(configFile: string, configs: InputOptions[], command: any) { for (const config of configs) { promise = promise.then(() => { const warnings = batchWarnings(); - const { inputOptions, outputOptions, deprecations, optionError } = mergeOptions({ + const { inputOptions, outputOptions, optionError } = mergeOptions({ config, command, defaultOnWarnHandler: warnings.add }); - if (deprecations.length) { - inputOptions.onwarn({ - code: 'DEPRECATED_OPTIONS', - message: `The following options have been renamed — please update your config: ${deprecations - .map(option => `${option.old} -> ${option.new}`) - .join(', ')}`, - deprecations - }); - } - if (optionError) inputOptions.onwarn({ code: 'UNKNOWN_OPTION', message: optionError }); return build(inputOptions, outputOptions, warnings, command.silent); }); diff --git a/bin/src/run/loadConfigFile.ts b/bin/src/run/loadConfigFile.ts index 9b2013ad574..8144b6dfd4c 100644 --- a/bin/src/run/loadConfigFile.ts +++ b/bin/src/run/loadConfigFile.ts @@ -1,7 +1,7 @@ import path from 'path'; import rollup from 'rollup'; import tc from 'turbocolor'; -import { InputOptions, RollupSingleFileBuild } from '../../../src/rollup/types'; +import { InputOptions, RollupBuild, RollupOutput } from '../../../src/rollup/types'; import relativeId from '../../../src/utils/relativeId'; import { handleError, stderr } from '../logging'; import batchWarnings from './batchWarnings'; @@ -20,12 +20,13 @@ export default function loadConfigFile( return rollup .rollup({ input: configFile, + treeshake: false, external: (id: string) => { return (id[0] !== '.' && !path.isAbsolute(id)) || id.slice(-5, id.length) === '.json'; }, onwarn: warnings.add }) - .then((bundle: RollupSingleFileBuild) => { + .then((bundle: RollupBuild) => { if (!silent && warnings.count > 0) { stderr(tc.bold(`loaded ${relativeId(configFile)} with warnings`)); warnings.flush(); @@ -35,7 +36,7 @@ export default function loadConfigFile( format: 'cjs' }); }) - .then(({ code }: { code: string }) => { + .then(({ output: [{ code }] }: RollupOutput) => { // temporarily override require const defaultLoader = require.extensions['.js']; require.extensions['.js'] = (module: NodeModuleWithCompile, filename: string) => { diff --git a/bin/src/run/watch.ts b/bin/src/run/watch.ts index 8a2410c85d4..5c7b3f44036 100644 --- a/bin/src/run/watch.ts +++ b/bin/src/run/watch.ts @@ -8,7 +8,6 @@ import { InputOption, RollupBuild, RollupError, - RollupSingleFileBuild, RollupWatchOptions } from '../../../src/rollup/types'; import mergeOptions from '../../../src/utils/mergeOptions'; @@ -18,13 +17,14 @@ import alternateScreen from './alternateScreen'; import batchWarnings from './batchWarnings'; import loadConfigFile from './loadConfigFile'; import { printTimings } from './timings'; + interface WatchEvent { code?: string; error?: RollupError | Error; input?: InputOption; output?: string[]; duration?: number; - result?: RollupSingleFileBuild | RollupBuild; + result?: RollupBuild; } interface Watcher { @@ -69,10 +69,6 @@ export default function watch( if (!result.watch) result.watch = {}; - if (merged.deprecations.length) { - (<{ _deprecations: any }>result.watch)._deprecations = merged.deprecations; - } - if (merged.optionError) merged.inputOptions.onwarn({ message: merged.optionError, @@ -121,8 +117,8 @@ export default function watch( input = Array.isArray(input) ? input.join(', ') : Object.keys(input) - .map(key => (>input)[key]) - .join(', '); + .map(key => (>input)[key]) + .join(', '); } stderr( tc.cyan( diff --git a/docs/00-introduction.md b/docs/00-introduction.md index 1b0c28c37e3..1e82ad10151 100755 --- a/docs/00-introduction.md +++ b/docs/00-introduction.md @@ -4,7 +4,7 @@ title: Introduction ### Overview -Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application. It uses the new standardized format for code modules included in the ES6 revision of JavaScript, instead of previous idiosyncratic solutions such as CommonJS and AMD. ES6 modules let you freely and seamlessly combine the most useful individual functions from your favorite libraries. This will eventually be possible natively, but Rollup lets you do it today. +Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application. It uses the new standardized format for code modules included in the ES6 revision of JavaScript, instead of previous idiosyncratic solutions such as CommonJS and AMD. ES modules let you freely and seamlessly combine the most useful individual functions from your favorite libraries. This will eventually be possible natively everywhere, but Rollup lets you do it today. ### Quick start @@ -41,11 +41,11 @@ $ rollup main.js --file bundle.js --format umd --name "myBundle" Developing software is usually easier if you break your project into smaller separate pieces, since that often removes unexpected interactions and dramatically reduces the complexity of the problems you'll need to solve, and simply writing smaller projects in the first place [isn't necessarily the answer](https://medium.com/@Rich_Harris/small-modules-it-s-not-quite-that-simple-3ca532d65de4). Unfortunately, JavaScript has not historically included this capability as a core feature in the language. -This finally changed with the ES6 revision of JavaScript, which includes a syntax for importing and exporting functions and data so they can be shared between separate scripts. The specification is now fixed, but it is not yet implemented in browsers or Node.js. Rollup allows you to write your code using the new module system, and will then compile it back down to existing supported formats such as CommonJS modules, AMD modules, and IIFE-style scripts. This means that you get to *write future-proof code*, and you also get the tremendous benefits of... +This finally changed with the ES6 revision of JavaScript, which includes a syntax for importing and exporting functions and data so they can be shared between separate scripts. The specification is now fixed, but it is only implemented in modern browsers and not finalised in Node.js. Rollup allows you to write your code using the new module system, and will then compile it back down to existing supported formats such as CommonJS modules, AMD modules, and IIFE-style scripts. This means that you get to *write future-proof code*, and you also get the tremendous benefits of... ### Tree-Shaking -In addition to enabling the use of ES6 modules, Rollup also statically analyzes the code you are importing, and will exclude anything that isn't actually used. This allows you to build on top of existing tools and modules without adding extra dependencies or bloating the size of your project. +In addition to enabling the use of ES modules, Rollup also statically analyzes the code you are importing, and will exclude anything that isn't actually used. This allows you to build on top of existing tools and modules without adding extra dependencies or bloating the size of your project. For example, with CommonJS, the *entire tool or library must be imported*. @@ -57,7 +57,7 @@ const query = 'Rollup'; utils.ajax(`https://api.example.com?search=${query}`).then(handleResponse); ``` -But with ES6 modules, instead of importing the whole `utils` object, we can just import the one `ajax` function we need: +But with ES modules, instead of importing the whole `utils` object, we can just import the one `ajax` function we need: ```js // import the ajax function with an ES6 import statement @@ -67,7 +67,7 @@ const query = 'Rollup'; ajax(`https://api.example.com?search=${query}`).then(handleResponse); ``` -Because Rollup includes the bare minimum, it results in lighter, faster, and less complicated libraries and applications. Since this approach is based on explicit `import` and `export` statements, it is more effective than simply running an automated minifier to detect unused variables in the compiled output code. +Because Rollup includes the bare minimum, it results in lighter, faster, and less complicated libraries and applications. Since this approach can utilise explicit `import` and `export` statements, it is more effective than simply running an automated minifier to detect unused variables in the compiled output code. ### Compatibility @@ -76,12 +76,6 @@ Because Rollup includes the bare minimum, it results in lighter, faster, and les Rollup can import existing CommonJS modules [through a plugin](https://github.com/rollup/rollup-plugin-commonjs). -#### Publishing ES6 Modules - -To make sure your ES6 modules are immediately usable by tools that work with CommonJS such as Node.js and webpack, you can use Rollup to compile to UMD or CommonJS format, and then point to that compiled version with the `main` property in your `package.json` file. If your `package.json` file also has a `module` field, ES6-aware tools like Rollup and [webpack 2+](https://webpack.js.org/) will [import the ES6 module version](https://github.com/rollup/rollup/wiki/pkg.module) directly. - -### Links - -- step-by-step [tutorial video series](https://code.lengstorf.com/learn-rollup-js/), with accompanying written walkthrough -- miscellaneous issues in the [wiki](https://github.com/rollup/rollup/wiki) +#### Publishing ES Modules +To make sure your ES modules are immediately usable by tools that work with CommonJS such as Node.js and webpack, you can use Rollup to compile to UMD or CommonJS format, and then point to that compiled version with the `main` property in your `package.json` file. If your `package.json` file also has a `module` field, ESM-aware tools like Rollup and [webpack 2+](https://webpack.js.org/) will [import the ES module version](https://github.com/rollup/rollup/wiki/pkg.module) directly. diff --git a/docs/01-command-line-reference.md b/docs/01-command-line-reference.md index 4f12be99a14..ba7fd6cfbbf 100755 --- a/docs/01-command-line-reference.md +++ b/docs/01-command-line-reference.md @@ -8,7 +8,7 @@ Rollup should typically be used from the command line. You can provide an optio Rollup configuration files are optional, but they are powerful and convenient and thus **recommended**. -A config file is an ES6 module that exports a default object with the desired options. Typically, it is called `rollup.config.js` and sits in the root directory of your project. +A config file is an ES module that exports a default object with the desired options. Typically, it is called `rollup.config.js` and sits in the root directory of your project. Also you can use CJS modules syntax for the config file. @@ -31,66 +31,75 @@ Consult the [big list of options](guide/en#big-list-of-options) for details on e export default { // can be an array (for multiple inputs) // core input options - input, // required external, + input, // required plugins, // advanced input options + cache, + inlineDynamicImports, + manualChunks, onwarn, - perf, + preserveModules, // danger zone acorn, acornInjectPlugins, - treeshake, context, moduleContext, + preserveSymlinks, + shimMissingExports, + treeshake, // experimental - experimentalCodeSplitting, - manualChunks, - experimentalOptimizeChunks, chunkGroupingSize, + experimentalCacheExpiry, + experimentalOptimizeChunks, + experimentalTopLevelAwait, + perf, - output: { // required (can be an array, for multiple outputs) + output: { // required (can be an array, for multiple outputs) // core output options - format, // required - file, dir, - name, + file, + format, // required globals, + name, // advanced output options - paths, + assetFileNames, banner, + chunkFileNames, + compact, + entryFileNames, + extend, footer, + interop, intro, outro, + paths, sourcemap, + sourcemapExcludeSources, sourcemapFile, sourcemapPathTransform, - interop, - extend, // danger zone - exports, amd, - indent, - strict, + esModule, + exports, freeze, + indent, namespaceToStringTag, - - // experimental - entryFileNames, - chunkFileNames, - assetFileNames + noConflict, + preferConst, + strict }, watch: { chokidar, - include, + clearScreen, exclude, - clearScreen + include } }; ``` @@ -125,7 +134,7 @@ If you want to create your config asynchronously, Rollup can also handle a `Prom ```javascript // rollup.config.js -import fetch from 'node-fetch'; +import fetch from 'node-fetch'; export default fetch('/some-remote-service-or-file-which-returns-actual-config'); ``` @@ -179,26 +188,44 @@ Many options have command line equivalents. Any arguments passed here will overr ```text -c, --config Use this config file (if argument is used but value is unspecified, defaults to rollup.config.js) --i, --input Input (alternative to ) --o, --file Output (if absent, prints to stdout) --f, --format [esm] Type of output (amd, cjs, esm, iife, umd) +-d, --dir Directory for chunks (if absent, prints to stdout) -e, --external Comma-separate list of module IDs to exclude --g, --globals Comma-separate list of `module ID:Global` pairs - Any module IDs defined here are added to external --n, --name Name for UMD export +-f, --format Type of output (amd, cjs, esm, iife, umd) +-g, --globals Comma-separate list of `moduleID:Global` pairs +-i, --input Input (alternative to ) -m, --sourcemap Generate sourcemap (`-m inline` for inline map) ---amd.id ID for AMD module (default is anonymous) ---amd.define Function to use in place of `define` ---no-strict Don't emit a `"use strict";` in the generated modules. +-n, --name Name for UMD export +-o, --file Single output file (if absent, prints to stdout) +--amd.id ID for AMD module (default is anonymous) +--amd.define Function to use in place of `define` +--assetFileNames Name pattern for emitted assets +--banner Code to insert at top of bundle (outside wrapper) +--chunkFileNames Name pattern for emitted secondary chunks +--compact Minify wrapper code +--context Specify top-level `this` value +--entryFileNames Name pattern for emitted entry chunks +--no-esModule Do not add __esModule property +--exports Specify export mode (auto, default, named, none) +--extend Extend global variable defined by --name +--footer Code to insert at end of bundle (outside wrapper) +--no-freeze Do not freeze namespace objects --no-indent Don't indent result ---environment Environment variables passed to config file ---noConflict Generate a noConflict method for UMD globals ---no-treeshake Disable tree-shaking ---intro Content to insert at top of bundle (inside wrapper) ---outro Content to insert at end of bundle (inside wrapper) ---banner Content to insert at top of bundle (outside wrapper) ---footer Content to insert at end of bundle (outside wrapper) --no-interop Do not include interop block +--inlineDynamicImports Create single bundle when using dynamic imports +--intro Code to insert at top of bundle (inside wrapper) +--namespaceToStringTag Create proper `.toString` methods for namespaces +--noConflict Generate a noConflict method for UMD globals +--no-strict Don't emit `"use strict";` in the generated modules +--outro Code to insert at end of bundle (inside wrapper) +--preferConst Use `const` instead of `var` for exports +--preserveModules Preserve module structure +--preserveSymlinks Do not follow symlinks when resolving files +--shimMissingExports Create shim variables for missing exports +--sourcemapExcludeSources Do not include source code in source maps +--sourcemapFile Specify bundle position for source maps +--no-treeshake Disable tree-shaking optimisations +--no-treeshake.propertyReadSideEffects Ignore property access side-effects +--treeshake.pureExternalModules Assume side-effect free externals ``` In addition, the following arguments can be used: diff --git a/docs/02-javascript-api.md b/docs/02-javascript-api.md index add5d651852..4d246b2979c 100755 --- a/docs/02-javascript-api.md +++ b/docs/02-javascript-api.md @@ -19,31 +19,45 @@ async function build() { // create a bundle const bundle = await rollup.rollup(inputOptions); - console.log(bundle.imports); // an array of external dependencies - console.log(bundle.exports); // an array of names exported by the entry point - console.log(bundle.modules); // an array of module objects - - // generate code and a sourcemap - const output = await bundle.generate(outputOptions); - - // output contains the following information about the generated bundle: - // { - // code: string, // the generated JS code - // map: string | null, // sourcemaps if present - // dynamicImports: string[], // external modules imported dynamically by the bundle - // exports: string[], // exported variable names - // fileName: string, // the generated bundle file name - // imports: string[], // external modules imported statically by the bundle - // modules: { // a list of all modules in the bundle with tree-shaking statistics - // [id: string]: { - // renderedExports: string[]; - // removedExports: string[]; - // renderedLength: number; - // originalLength: number; - // }; - // } - // } - console.log(output); + console.log(bundle.watchFiles); // an array of file names this bundle depends on + + // generate code + const { output } = await bundle.generate(outputOptions); + + for (const chunkOrAsset of output) { + if (chunkOrAsset.isAsset) { + // For assets, this contains + // { + // isAsset: true, // signifies that this is an asset + // fileName: string, // the asset file name + // source: string | Buffer // the asset source + // } + console.log('Asset', chunkOrAsset); + } else { + // For chunks, this contains + // { + // code: string, // the generated JS code + // dynamicImports: string[], // external modules imported dynamically by the chunk + // exports: string[], // exported variable names + // facadeModuleId: string | null, // the id of a module that this chunk corresponds to + // fileName: string, // the chunk file name + // imports: string[], // external modules imported statically by the chunk + // isDynamicEntry: boolean, // is this chunk a dynamic entry point + // isEntry: boolean, // is this chunk a static entry point + // map: string | null, // sourcemaps if present + // modules: { // information about the modules in this chunk + // [id: string]: { + // renderedExports: string[]; // exported variable names that were included + // removedExports: string[]; // exported variable names that were removed + // renderedLength: number; // the length of the remaining code in this module + // originalLength: number; // the original length of the code in this module + // }; + // }, + // name: string // the name of this chunk as used in naming patterns + // } + console.log('Chunk', chunkOrAsset.modules); + } + } // or write the bundle to disk await bundle.write(outputOptions); @@ -52,80 +66,85 @@ async function build() { build(); ``` - #### inputOptions The `inputOptions` object can contain the following properties (see the [big list of options](guide/en#big-list-of-options) for full details on these): ```js const inputOptions = { - // core options - input, // the only required option + // core input options external, + input, // required plugins, - // advanced options - onwarn, + // advanced input options cache, - perf, + inlineDynamicImports, + manualChunks, + onwarn, + preserveModules, // danger zone acorn, acornInjectPlugins, - treeshake, context, moduleContext, + preserveSymlinks, + shimMissingExports, + treeshake, // experimental - experimentalCodeSplitting, - manualChunks, + chunkGroupingSize, + experimentalCacheExpiry, experimentalOptimizeChunks, - chunkGroupingSize + experimentalTopLevelAwait, + perf }; ``` - #### outputOptions The `outputOptions` object can contain the following properties (see the [big list of options](guide/en#big-list-of-options) for full details on these): ```js const outputOptions = { - // core options - format, // required - file, - dir, - name, - globals, - - // advanced options - paths, - banner, - footer, - intro, - outro, - sourcemap, - sourcemapFile, - sourcemapPathTransform, - interop, - extend, - - // danger zone - exports, - amd, - indent, - strict, - freeze, - namespaceToStringTag, - - // experimental - entryFileNames, - chunkFileNames, - assetFileNames + // core output options + dir, + file, + format, // required + globals, + name, + + // advanced output options + assetFileNames, + banner, + chunkFileNames, + compact, + entryFileNames, + extend, + footer, + interop, + intro, + outro, + paths, + sourcemap, + sourcemapExcludeSources, + sourcemapFile, + sourcemapPathTransform, + + // danger zone + amd, + esModule, + exports, + freeze, + indent, + namespaceToStringTag, + noConflict, + preferConst, + strict }; ``` - ### rollup.watch Rollup also provides a `rollup.watch` function that rebuilds your bundle when it detects that the individual modules have changed on disk. It is used internally when you run Rollup from the command line with the `--watch` flag. @@ -160,22 +179,11 @@ const watchOptions = { output: [outputOptions], watch: { chokidar, - include, + clearScreen, exclude, - clearScreen + include } }; ``` See above for details on `inputOptions` and `outputOptions`, or consult the [big list of options](guide/en#big-list-of-options) for info on `chokidar`, `include` and `exclude`. - - -### TypeScript Declarations - -If you'd like to use the API in a TypeScript environment you can do so, as now we ship TypeScript declarations. - -You need to install some dependencies in case you have [skipLibCheck](https://www.typescriptlang.org/docs/handbook/compiler-options.html) turned off. - -```console -npm install @types/acorn @types/chokidar source-map magic-string --only=dev -``` diff --git a/docs/03-es-module-syntax.md b/docs/03-es-module-syntax.md index 0f784b91e0f..5609f9a35ad 100755 --- a/docs/03-es-module-syntax.md +++ b/docs/03-es-module-syntax.md @@ -2,16 +2,11 @@ title: ES Module Syntax --- -The following is intended as a lightweight reference for the module behaviors -defined in the [ES2015 specification](https://www.ecma-international.org/ecma-262/6.0/), -since a proper understanding of the import and export statements are essential -to successful use of Rollup. +The following is intended as a lightweight reference for the module behaviors defined in the [ES2015 specification](https://www.ecma-international.org/ecma-262/6.0/), since a proper understanding of the import and export statements are essential to the successful use of Rollup. ### Importing -Imported values cannot be reassigned, though imported objects and arrays *can* -be mutated (and the exporting module, and any other importers, will be affected -by the mutation). In that way, they behave similarly to `const` declarations. +Imported values cannot be reassigned, though imported objects and arrays *can* be mutated (and the exporting module, and any other importers, will be affected by the mutation). In that way, they behave similarly to `const` declarations. #### Named Imports @@ -22,8 +17,7 @@ Import a specific item from a source module, with its original name. import { something } from './module.js'; ``` -Import a specific item from a source module, with a custom name assigned upon -import. +Import a specific item from a source module, with a custom name assigned upon import. ```js import { something as somethingElse } from './module.js'; @@ -31,16 +25,13 @@ import { something as somethingElse } from './module.js'; #### Namespace Imports -Import everything from the source module as an object which exposes all the -source module's named exports as properties and methods. Default exports are -excluded from this object. +Import everything from the source module as an object which exposes all the source module's named exports as properties and methods. ```js import * as module from './module.js' ``` -The `something` example from above would then be attached to the imported object -as a property, e.g. `module.something`. +The `something` example from above would then be attached to the imported object as a property, e.g. `module.something`. If present, the default export can be accessed via `module.default`. #### Default Import @@ -62,8 +53,7 @@ This is useful for polyfills, or when the primary purpose of the imported code i #### Dynamic Import -Import modules using the -[dynamic import API](https://github.com/tc39/proposal-dynamic-import#import). +Import modules using the [dynamic import API](https://github.com/tc39/proposal-dynamic-import#import). ```js import('./modules.js').then(({ default: DefaultExport, NamedExport })=> { diff --git a/docs/04-tutorial.md b/docs/04-tutorial.md index 6034d219745..4b04435e53c 100755 --- a/docs/04-tutorial.md +++ b/docs/04-tutorial.md @@ -198,37 +198,108 @@ module.exports = main; _Note: Only the data we actually need gets imported – `name` and `devDependencies` and other parts of `package.json` are ignored. That's **tree-shaking** in action!_ -### Experimental Code Splitting +### Code Splitting -To use the new experimental code splitting feature, we add a second *entry point* called `src/main2.js` that itself dynamically loads main.js: +To use the code splitting feature, we got back to the original example and modify `src/main.js` to load `src/foo.js` dynamically instead of statically: ```js -// src/main2.js +// src/main.js export default function () { - return import('./main.js').then(({ default: main }) => { - main(); - }); + import('./foo.js').then(({ default: foo }) => console.log(foo)); } ``` -We can then pass both entry points to the rollup build, and instead of an output file we set a folder to output to with the `--dir` option (also passing the experimental flags): +Rollup will use the dynamic import to create a separate chunk that is only loaded on demand. In order for Rollup to know where to place the second chunk, instead of passing the `--file` option we set a folder to output to with the `--dir` option: ```console -rollup src/main.js src/main2.js -f cjs --dir dist --experimentalCodeSplitting +rollup src/main.js -f cjs -d dist ``` -Either built entry point can then be run in NodeJS without duplicating any code between the modules: +This will create a folder `dist` containing two files, `main.js` and `chunk-[hash].js`, where `[hash]` is a content based hash string. You can supply your own naming patterns by specifying the [`output.chunkFileNames`](guide/en#output-chunkfilenames) and [`output.entryFileNames`](guide/en#output-entryfilenames) options. + +You can still run your code as before with the same output, albeit a little slower as loading and parsing of `./foo.js` will only commence once we call the exported function for the first time. ```console -node -e "require('./dist/main2.js')()" +node -e "require('./dist/main.js')()" +``` + +If we do not use the `--dir` option, Rollup will again print the chunks to `stdout`, adding comments to highlight the chunk boundaries: + +```js +//→ main.js: +'use strict'; + +function main () { + Promise.resolve(require('./chunk-b8774ea3.js')).then(({ default: foo }) => console.log(foo)); +} + +module.exports = main; + +//→ chunk-b8774ea3.js: +'use strict'; + +var foo = 'hello world!'; + +exports.default = foo; +``` + +This is very useful if you want to load and parse expensive features only once they are used. + +A different use for code-splitting is the ability to specify several entry points that share some dependencies. Again we extend our example to add a second entry point `src/main2.js` that statically imports `src/foo.js` just like we did in the original example: + +```js +// src/main2.js +import foo from './foo.js'; +export default function () { + console.log(foo); +} ``` -You can build the same code for the browser, for native ES modules, an AMD loader or SystemJS. +If we supply both entry points to rollup, three chunks are created: + +```console +rollup src/main.js src/main2.js -f cjs +``` + +will output + +```js +//→ main.js: +'use strict'; + +function main () { + Promise.resolve(require('./chunk-b8774ea3.js')).then(({ default: foo }) => console.log(foo)); +} + +module.exports = main; + +//→ main2.js: +'use strict'; + +var foo_js = require('./chunk-b8774ea3.js'); + +function main2 () { + console.log(foo_js.default); +} + +module.exports = main2; + +//→ chunk-b8774ea3.js: +'use strict'; + +var foo = 'hello world!'; + +exports.default = foo; +``` + +Notice how both entry points import the same shared chunk. Rollup will never duplicate code and instead create additional chunks to only ever load the bare minimum necessary. Again, passing the `--dir` option will write the files to disk. + +You can build the same code for the browser via native ES modules, an AMD loader or SystemJS. For example, with `-f esm` for native modules: ```console -rollup src/main.js src/main2.js -f esm --dir dist --experimentalCodeSplitting +rollup src/main.js src/main2.js -f esm -d dist ``` ```html @@ -242,7 +313,7 @@ rollup src/main.js src/main2.js -f esm --dir dist --experimentalCodeSplitting Or alternatively, for SystemJS with `-f system`: ```console -rollup src/main.js src/main2.js -f system --dir dist --experimentalCodeSplitting +rollup src/main.js src/main2.js -f system -d dist ``` Install SystemJS via @@ -261,3 +332,5 @@ And then load either or both entry points in an HTML page as needed: .then(({ default: main }) => main()); ``` + +See [rollup-starter-code-splitting](https://github.com/rollup/rollup-starter-code-splitting) for an example on how to set up a web app that uses native ES modules on browsers that support them with a fallback to SystemJS if necessary. diff --git a/docs/05-plugins.md b/docs/05-plugins.md index b1e8a0bd50f..8147b237436 100644 --- a/docs/05-plugins.md +++ b/docs/05-plugins.md @@ -4,7 +4,7 @@ title: Plugins ### Plugins Overview -A Rollup plugin is a package which exports a function that returns an object with one or more of the [properties](guide/en#properties) and [hooks](guide/en#hooks) described below, and which follows our [conventions](guide/en#conventions). +A Rollup plugin is an object with one or more of the [properties](guide/en#properties) and [hooks](guide/en#hooks) described below, and which follows our [conventions](guide/en#conventions). A plugin should be distributed as a packages which exports a function that can be called with plugin specific options and returns such an object. Plugins allow you to customise Rollup's behaviour by, for example, transpiling code before bundling, or finding third-party modules in your `node_modules` folder. For an example on how to use them, see [Using plugins](guide/en#using-plugins). @@ -59,7 +59,7 @@ export default ({ ### Properties #### `name` -Type: `String` +Type: `string` The name of the plugin, for use in error messages and warnings. @@ -68,88 +68,111 @@ The name of the plugin, for use in error messages and warnings. In addition to properties defining the identity of your plugin, you may also specify properties that correspond to available build hooks. Hooks can affect how a build is run, provide information about a build, or modify a build once complete. #### `banner` -Type: `String|Function` +Type: `string | (() => string | Promise)` -A `String`, or a `Function` that returns a `String` or `Promise`. Cf. [output.banner/output.footer](output-banner-output-footer-banner-footer). +Cf. [`output.banner/output.footer`](guide/en#output-banner-output-footer). #### `buildEnd` -Type: `Function`
-Signature: `( error ) => void` +Type: `(error?: Error) => void | Promise` Called when rollup has finished bundling, but before `generate` or `write` is called; you can also return a Promise. If an error occurred during the build, it is passed on to this hook. #### `buildStart` -Type: `Function`
-Signature: `( ) => (void|Promise)` +Type: `(options: InputOptions) => void | Promise` Called on each `rollup.rollup` build. #### `footer` -Type: `String|Function` +Type: `string | (() => string | Promise)` -A `String`, or a `Function` that returns a `String` or `Promise`. Cf. [output.banner/output.footer](output-banner-output-footer-banner-footer). +Cf. [`output.banner/output.footer`](guide/en#output-banner-output-footer). #### `generateBundle` -Type: `Function`
-Signature: `( outputOptions, bundle, isWrite ) => (void|Promise)` +Type: `(options: OutputOptions, bundle: { [fileName: string]: AssetInfo | ChunkInfo }, isWrite: boolean) => void | Promise` -Called at the end of `bundle.generate()` or `bundle.write()`. `bundle` provides the full list of files being written or generated along with their details. +Called at the end of `bundle.generate()` or `bundle.write()`. `bundle` provides the full list of files being written or generated along with their details: + +``` +// AssetInfo +{ + fileName: string, + isAsset: true, + source: string | Buffer +} + +// ChunkInfo +{ + dynamicImports: string[], + exports: string[], + facadeModuleId: string | null, + fileName: string, + imports: string[], + isDynamicEntry: boolean, + isEntry: boolean, + modules: { + [id: string]: { + renderedExports: string[], + removedExports: string[], + renderedLength: number, + originalLength: number + }, + }, + name: string +} +``` #### `intro` -Type: `String|Function` +Type: `string | (() => string | Promise)` -A `String`, or a `Function` that returns a `String` or `Promise`. Cf. [output.intro/output.outro](output-intro-output-outro-intro-outro). +Cf. [`output.intro/output.outro`](guide/en#output-intro-output-outro). #### `load` -Type: `Function`
-Signature: `( id ) => (code | { code, map } | Promise)` +Type: `(id: string) => string | null | { code: string, map?: string | SourceMap } | Promise<...>` Defines a custom loader. Returning `null` defers to other `load` functions (and eventually the default behavior of loading from the file system). #### `options` -Type: `Function`
-Signature: `( inputOptions ) => options` +Type: `(options: InputOptions) => InputOptions | null` Reads and replaces or manipulates the options object passed to `rollup.rollup`. Returning `null` does not replace anything. #### `outro` -Type: `String|Function` +Type: `string | (() => string | Promise)` -A `String`, or a `Function` that returns a `String` or `Promise`. Cf. [output.intro/output.outro](output-intro-output-outro-intro-outro). +Cf. [`output.intro/output.outro`](guide/en#output-intro-output-outro). #### `renderChunk` -Type: `Function`
-Signature: `(code, { modules, exports, imports, fileName, isEntry }, outputOptions) => (code | { code, map} | Promise)` +Type: `(code: string, chunk: ChunkInfo, options: OutputOptions) => string | { code: string, map: SourceMap } | null | Promise<...>` Can be used to transform individual chunks. Called for each Rollup output chunk file. Returning `null` will apply no transformations. #### `renderError` -Type: `Function`
-Signature: `( error ) => void` +Type: `(error: Error) => void | Promise` Called when rollup encounters an error during `bundle.generate()` or `bundle.write()`. The error is passed to this hook. To get notified when generation completes successfully, use the `generateBundle` hook. #### `renderStart` -Type: `Function`
-Signature: `( ) => (void|Promise)` +Type: `() => void | Promise` Called initially each time `bundle.generate()` or `bundle.write()` is called. To get notified when generation has completed, use the `generateBundle` and `renderError` hooks. +#### `resolveDynamicImport` +Type: `(specifier: string | ESTree.Node, importer: string) => string | false | null | Promise<...>` + +Defines a custom resolver for dynamic imports. In case a dynamic import is not passed a string as argument, this hook gets access to the raw AST nodes to analyze. Returning `null` will defer to other resolvers and eventually to `resolveId` if this is possible; returning `false` signals that the import should be kept as it is and not be passed to other resolvers thus making it external. Note that the return value of this hook will not be passed to `resolveId` afterwards; if you need access to the static resolution algorithm, you can use `this.resolveId(importee, importer)` on the plugin context. + #### `resolveId` -Type: `Function`
-Signature: `( importee, importer ) => (id|Promise)` +Type: `(importee: string, importer: string) => string | false | null | Promise<...>` -Defines a custom resolver. A resolver loader can be useful for e.g. locating third-party dependencies. Returning `null` or `undefined` defers to other `resolveId` functions (and eventually the default resolution behavior); returning `false` signals that `importee` should be treated as an external module and not included in the bundle. +Defines a custom resolver. A resolver loader can be useful for e.g. locating third-party dependencies. Returning `null` defers to other `resolveId` functions (and eventually the default resolution behavior); returning `false` signals that `importee` should be treated as an external module and not included in the bundle. #### `transform` -Type: `Function`
-Signature: `( source, id ) => (code|{ code, map, dependencies }|Promise)` +Type: `(code: string, id: string) => string | { code: string, map?: string | SourceMap, ast? : ESTree.Program } | null | Promise<...>` -Can be used to transform individual modules. In `--watch` mode, also watch for changes in any of the files or directories in the `dependencies` array. +Can be used to transform individual modules. #### `watchChange` -Type: `Function`
-Signature: `(file) => { }` +Type: `(id: string) => void` Notifies a plugin whenever rollup has detected a change to a monitored file in `--watch` mode. @@ -172,23 +195,23 @@ chunk ) => code | { code, map}` chunk transformer function. More properties may be supported in future, as and when they prove necessary. -### Context +### Plugin Context A number of utility functions and informational bits can be accessed from within all [hooks](guide/en#hooks) via `this`: -#### `this.emitAsset( assetName, source )` +#### `this.emitAsset(assetName: string, source: string) => void` Emits a custom file to include in the build output, returning its `assetId`. You can defer setting the source if you provide it later via `this.setAssetSource(assetId)`. A string or Buffer source must be set for each asset through either method or an error will be thrown on generate completion. -#### `this.error( error [, position] )` +#### `this.error(error: string | Error, position?: number) => void` Structurally equivalent to `this.warn`, except that it will also abort the bundling process. -#### `this.getAssetFileName( assetId )` +#### `this.getAssetFileName(assetId: string) => string` Get the file name of an asset, according to the `assetFileNames` output option pattern. -#### `this.getModuleInfo( moduleId )` +#### `this.getModuleInfo(moduleId: string) => ModuleInfo` Returns additional information about the module in question in the form @@ -202,16 +225,15 @@ Returns additional information about the module in question in the form If the module id cannot be found, an error is thrown. -#### `this.isExternal( id, parentId, isResolved )` +#### `this.isExternal(id: string, parentId: string, isResolved: boolean): boolean` Determine if a given module ID is external. -#### `this.meta` +#### `this.meta: {rollupVersion: string}` -An `Object` containing potentially useful Rollup metadata. eg. -`this.meta.rollupVersion` +An `Object` containing potentially useful Rollup metadata. -#### `this.moduleIds` +#### `this.moduleIds: IterableIterator` An `Iterator` that gives access to all module ids in the current graph. It can be iterated via @@ -221,23 +243,23 @@ for (const moduleId of this.moduleIds) { /* ... */ } or converted into an Array via `Array.from(this.moduleIds)`. -#### `this.parse( code, acornOptions )` +#### `this.parse(code: string, acornOptions: AcornOptions) => ESTree.Program` Use Rollup's internal acorn instance to parse code to an AST. -#### `this.resolveId( importee, importer )` +#### `this.resolveId(importee: string, importer: string) => string` Resolve imports to module ids (i.e. file names). Uses the same hooks as Rollup itself. -#### `this.setAssetSource( assetId, source )` +#### `this.setAssetSource(assetId: string, source: string | Buffer) => void` Set the deferred source of an asset. -#### `this.warn( warning [, position] )` +#### `this.warn(warning: string | RollupWarning, position?: number )` Using this method will queue warnings for a build. These warnings will be printed by the CLI just like internally-generated warnings (except with the plugin name), or captured by custom `onwarn` handlers. -The `warning` argument can be a `String` or an `Object` with (at minimum) a `message` property: +The `warning` argument can be a `string` or an object with (at minimum) a `message` property: ```js this.warn( 'hmm...' ); diff --git a/docs/06-faqs.md b/docs/06-faqs.md index cc7875717fd..eaa8142bac4 100755 --- a/docs/06-faqs.md +++ b/docs/06-faqs.md @@ -12,7 +12,7 @@ Tree-shaking, also known as "live code inclusion," is the process of eliminating #### How do I use Rollup in Node.js with CommonJS modules? -Rollup strives to implement the specification for ES modules, not necessarily the behaviors of Node.js, NPM, `require()`, and CommonJS. Consequently, loading of CommonJS modules and use of Node's module location resolution logic are both implemented as optional plugins, not included by default in the Rollup core. Just `npm install` the [CommonJS](https://github.com/rollup/rollup-plugin-commonjs) and [node-resolve](https://github.com/rollup/rollup-plugin-node-resolve) plugins and then enable them using a `rollup.config.js` file and you should be all set. If the modules import JSON files, you will also need the [json](https://github.com/rollup/rollup-plugin-json) plugin. +Rollup strives to implement the specification for ES modules, not necessarily the behaviors of Node.js, NPM, `require()`, and CommonJS. Consequently, loading of CommonJS modules and use of Node's module location resolution logic are both implemented as optional plugins, not included by default in the Rollup core. Just `npm install` the [commonjs](https://github.com/rollup/rollup-plugin-commonjs) and [node-resolve](https://github.com/rollup/rollup-plugin-node-resolve) plugins and then enable them using a `rollup.config.js` file and you should be all set. If the modules import JSON files, you will also need the [json](https://github.com/rollup/rollup-plugin-json) plugin. #### Why isn't node-resolve a built-in feature? diff --git a/docs/07-tools.md b/docs/07-tools.md index 86d7aa48b7d..ce52775c68d 100755 --- a/docs/07-tools.md +++ b/docs/07-tools.md @@ -70,7 +70,7 @@ This time, when you `npm run build`, no warning is emitted — the bundle contai #### rollup-plugin-commonjs -Some libraries expose ES6 modules that you can import as-is — `the-answer` is one such module. But at the moment, the majority of packages on NPM are exposed as CommonJS modules instead. Until that changes, we need to convert CommonJS to ES2015 before Rollup can process them. +Some libraries expose ES modules that you can import as-is — `the-answer` is one such module. But at the moment, the majority of packages on NPM are exposed as CommonJS modules instead. Until that changes, we need to convert CommonJS to ES2015 before Rollup can process them. The [rollup-plugin-commonjs](https://github.com/rollup/rollup-plugin-commonjs) plugin does exactly that. @@ -135,7 +135,7 @@ The array form of `external` does not handle wildcards, so this import will only Many developers use [Babel](https://babeljs.io/) in their projects in order to use the latest JavaScript features that aren't yet supported by browsers and Node.js. -The easiest way to use both Babel and Rollup is with [rollup-plugin-babel](https://github.com/rollup/rollup-plugin-babel). First; install the plugin: +The easiest way to use both Babel and Rollup is with [rollup-plugin-babel](https://github.com/rollup/rollup-plugin-babel). First, install the plugin: ```console npm i -D rollup-plugin-babel rollup-plugin-node-resolve @@ -165,21 +165,17 @@ export default { Before Babel will actually compile your code, it needs to be configured. Create a new file, `src/.babelrc`: -```js +```json { "presets": [ - ["@babel/env", { - "modules": false - }] - ], + ["@babel/env", {"modules": false}] + ] } ``` There are a few unusual elements to this setup. First, we're setting `"modules": false`, otherwise Babel will convert our modules to CommonJS before Rollup gets a chance to do its thing, causing it to fail. -Secondly; we're using the `external-helpers` plugin, which allows Rollup to include any 'helpers' just once at the top of the bundle, rather than including them in every module that uses them (which is the default behaviour). - -Thirdly; we're putting our `.babelrc` file in `src`, rather than the project root. This allows us to have a different `.babelrc` for things like tests, if we need that later – it's generally a good idea to have separate configuration for separate tasks. +Secondly, we're putting our `.babelrc` file in `src`, rather than the project root. This allows us to have a different `.babelrc` for things like tests, if we need that later – it's generally a good idea to have separate configuration for separate tasks. Now, before we run rollup, we need to install [`babel-core`](https://babeljs.io/docs/en/babel-core) diff --git a/docs/08-troubleshooting.md b/docs/08-troubleshooting.md index a9f4c0038ce..1dfd659c1b4 100644 --- a/docs/08-troubleshooting.md +++ b/docs/08-troubleshooting.md @@ -62,44 +62,6 @@ In a JavaScript module, `this` is `undefined` at the top level (i.e., outside fu There are occasional valid reasons for `this` to mean something else. If you're getting errors in your bundle, you can use `options.context` and `options.moduleContext` to change this behaviour. -### Warning: "Ambiguous default export" - -This warning is given when Rollup encounters a default export that *looks* like a function declaration, but is in fact parsed as a call expression: - -```js -export default function foo () { - // this looks like a function declaration, but it isn't! -} - -(function iife () { - // `foo` is immediately invoked because the parentheses - // around this block turn it into a function expression -}()) -``` - -If you want to export the function declaration, separate the declaration from the export: - -```js -function foo () { - // ... -} - -export default foo; -``` - -If you want to export the call expression but suppress the warning, wrap the function expression in parentheses to eliminate the ambiguity: - -```js -export default (function foo () { - // ... -}) - -(function iife () { - // ... -}()) -``` - - ### Warning: "Sourcemap is likely to be incorrect" You'll see this warning if you generate a sourcemap with your bundle (`sourceMap: true` or `sourceMap: 'inline'`) but you're using one or more plugins that transformed code without generating a sourcemap for the transformation. diff --git a/docs/999-big-list-of-options.md b/docs/999-big-list-of-options.md index d1631bebaa4..2f63ca2a5f7 100755 --- a/docs/999-big-list-of-options.md +++ b/docs/999-big-list-of-options.md @@ -4,119 +4,115 @@ title: Big list of options ### Core functionality -#### input *`-i`/`--input`* +#### external +Type: `string[] | (id: string, parentId: string, isResolved: boolean) => boolean`
+CLI: `-e`/`--external ` -`String` / `String[]` / `{ [entryName: String]: String }` The bundle's entry point(s) (e.g. your `main.js` or `app.js` or `index.js`). If you enable `experimentalCodeSplitting`, you can provide an array of entry points or object of named entry points which will be bundled to separate output chunks. +Either a function that takes an `id` and returns `true` (external) or `false` (not external), or an `Array` of module IDs that should remain external to the bundle. The IDs should be either: -#### output.file *`-o`/`--file`* +1. the name of an external dependency, exactly the way it is written in the import statement. I.e. to mark `import "dependency.js"` as external, use `"dependency.js"` while to mark `import "dependency"` as external, use `"dependency"`. +2. a resolved ID (like an absolute path to a file). -`String` The file to write to. Will also be used to generate sourcemaps, if applicable. If `experimentalCodeSplitting` is enabled and `input` is an array, you must specify `dir` instead of `file`. +```js +// rollup.config.js +import path from 'path'; -#### output.dir * `--dir`* +export default { + ..., + external: [ + 'some-externally-required-library', + path.resolve( __dirname, 'src/some-local-file-that-should-not-be-bundled.js' ) + ] +}; +``` -`String` The directory in which all generated chunks are placed. Only used if `experimentalCodeSplitting` is enabled and `input` is an array. In these cases this option replaces `file`. +When given as a command line argument, it should be a comma-separated list of IDs: -#### output.format *`-f`/`--format`* +```bash +rollup -i src/main.js ... -e foo,bar,baz +``` -`String` The format of the generated bundle. One of the following: +When providing a function, it is actually called with three parameters `(id, parent, isResolved)` that can give you more fine-grained control: -* `amd` – Asynchronous Module Definition, used with module loaders like RequireJS -* `cjs` – CommonJS, suitable for Node and Browserify/Webpack -* `esm` – Keep the bundle as an ES module file -* `iife` – A self-executing function, suitable for inclusion as a `