From 92426f5ab3ec211c108d40345fdf67cff04aa527 Mon Sep 17 00:00:00 2001 From: Axel D Date: Fri, 14 Dec 2018 16:52:20 +0100 Subject: [PATCH 01/13] CSS rules added for printing, script added to create chapter-wide documentation files from single files. --- concatenate-docs.js | 78 + package.json | 7 +- src/components/Footer/Footer.scss | 4 + src/components/Page/Page.jsx | 2 +- src/components/Page/Page.scss | 7 + src/components/PageLinks/PageLinks.scss | 4 + src/content/_all.md | 262 + src/content/api/_api_all.md | 3189 ++++++++++ src/content/concepts/_concepts_all.md | 1086 ++++ .../configuration/_configuration_all.md | 5315 +++++++++++++++++ src/content/contribute/_contribute_all.md | 979 +++ src/content/guides/_guides_all.md | 4880 +++++++++++++++ src/content/loaders/_loaders_all.md | 75 + src/content/migrate/_migrate_all.md | 786 +++ src/content/plugins/_plugins_all.md | 11 + 15 files changed, 16681 insertions(+), 4 deletions(-) create mode 100644 concatenate-docs.js create mode 100644 src/content/_all.md create mode 100644 src/content/api/_api_all.md create mode 100644 src/content/concepts/_concepts_all.md create mode 100644 src/content/configuration/_configuration_all.md create mode 100644 src/content/contribute/_contribute_all.md create mode 100644 src/content/guides/_guides_all.md create mode 100644 src/content/loaders/_loaders_all.md create mode 100644 src/content/migrate/_migrate_all.md create mode 100644 src/content/plugins/_plugins_all.md diff --git a/concatenate-docs.js b/concatenate-docs.js new file mode 100644 index 000000000000..5d2a7c48ec0f --- /dev/null +++ b/concatenate-docs.js @@ -0,0 +1,78 @@ +// start message +console.info("\x1b[0m\x1b[36mConcatenating help files of each directory to create chapter-wide help files to be used for printing help ...\x1b[0m"); + +// ------ various includes ------ +const fs = require("fs"); +const path = require("path"); +const os = require("os"); +const front = require("front-matter"); + +// root path +const rootPath = path.join("src", "content"); + +/* getDirectoryRecursive() recursively walks through + all sub directories of the provided root path, + concatenates the MarkDown files' content in + each directory, sorted by their FrontMatter sort + attribute, and creates a compound MarkDown file + named by using the directory name, prefixed by an + underscore and suffixed by "_all.md" from the + concatenated content in the corresponding directory. +*/ +(function getDirectoryRecursive(basePath) +{ + // log current working directory + console.log("\x1b[0m\x1b[32m " + basePath + "\x1b[0m"); + + // create destination file name of compound file + const targetFilePath = path.join(basePath, `${basePath.substr(rootPath.length).replace(/[/\\]/, "_")}_all.md`); + + if (fs.existsSync(targetFilePath)) fs.unlinkSync(targetFilePath); // delete target file if it already exists + + fs.readdir(basePath, function (err, fileNames) // list current working directory + { + if (err) throw err; + + let fileContents = []; + + for (let file of fileNames) // for each directory entry ... + { + const fullPath = path.join(basePath, file); + + if (fs.statSync(fullPath).isDirectory()) getDirectoryRecursive(fullPath); // if the directory entry is a directory, recurse into that directory + else if (fullPath.endsWith(".md")) // if the directory entry is a MarkDown file, add it to the list of files to be processed + { + let fc = fileContents[fileContents.length] = front(fs.readFileSync(fullPath).toString()); + + if (!fc.attributes.sort) --fileContents.length; // only include files providing a FrontMatter "sort" attribute + } + } + + // sort MarkDown files by FrontMatter "sort" attribute (QuickSort) + for (let i = 0;i < fileContents.length - 1;++i) + for (let j = i + 1;j < fileContents.length;++j) + { + const left = fileContents[i].attributes, right = fileContents[j].attributes; + + if (left.sort > right.sort + || left.sort == right.sort && left.title > right.title) + [fileContents[i], fileContents[j]] = [fileContents[j], fileContents[i]]; + } + + // write compound target file + const targetFile = fs.createWriteStream(targetFilePath); + + targetFile.on("error", (error) => { throw error; }); + + for (let file of fileContents) + { + targetFile.write(os.EOL + os.EOL + "# " + file.attributes.title + os.EOL); // use FrontMatter "title" attribute as main heading of target file + targetFile.write(file.body); + } + + targetFile.end(); + }); +})(rootPath); + +// end message +process.on("exit", () => { console.info("\x1b[0m\x1b[36mSuccessfully created \"_all.md\" help files in each directory within \"" + rootPath + "\".\x1b[0m"); }); \ No newline at end of file diff --git a/package.json b/package.json index 96f6834bb6f5..931acebc9f52 100644 --- a/package.json +++ b/package.json @@ -26,18 +26,19 @@ "scripts": { "start": "run-s -n init:generated fetch start-only", "start-only": "node ./antwar.bootstrap.js develop", - "build": "npm run init:generated && npm run fetch && rm -rf build/ && node ./antwar.bootstrap.js build && npm run sitemap && echo webpack.js.org > build/CNAME", + "build": "npm run init:generated && npm run fetch && rm -rf build/ && node ./antwar.bootstrap.js build && npm run sitemap && npm run chapterize && echo webpack.js.org > build/CNAME", "build-test": "npm run build && http-server build/", "deploy": "gh-pages -d build", "fetch": "sh src/scripts/fetch.sh", "init:generated": "mkdirp ./generated/loaders && mkdirp ./generated/plugins ", "lint": "run-s lint:*", "lint:js": "eslint . --ext .js,.jsx,.md", - "lint:markdown": "markdownlint --rules markdownlint-rule-emphasis-style --config ./.markdownlint.json *.md ./src/content/*.md ./src/content/**/*.md", + "lint:markdown": "markdownlint --rules markdownlint-rule-emphasis-style --config ./.markdownlint.json --ignore ./src/content/**/*_all.md *.md ./src/content/**/*.md", "lint:social": "alex . -q", "lint:prose": "cp .proselintrc ~/ && proselint src/content", "test": "npm run lint", - "sitemap": "cd build && sitemap-static --prefix=https://webpack.js.org/ > sitemap.xml" + "sitemap": "cd build && sitemap-static --prefix=https://webpack.js.org/ > sitemap.xml", + "chapterize": "node ./concatenate-docs.js" }, "husky": { "hooks": { diff --git a/src/components/Footer/Footer.scss b/src/components/Footer/Footer.scss index 106d52ec0de3..4388e8be401c 100644 --- a/src/components/Footer/Footer.scss +++ b/src/components/Footer/Footer.scss @@ -4,6 +4,10 @@ .footer { width: 100%; flex: 0 0 auto; + + @media print { + display: none !important; + } } .footer__inner { diff --git a/src/components/Page/Page.jsx b/src/components/Page/Page.jsx index a21ce4d20156..e2b93794f766 100644 --- a/src/components/Page/Page.jsx +++ b/src/components/Page/Page.jsx @@ -81,7 +81,7 @@ const Page = ({ page, section }) => { )} { contributors.length > 0 && ( -
+

Contributors

diff --git a/src/components/Page/Page.scss b/src/components/Page/Page.scss index 85c664e2fdfe..91b1b94bcafe 100644 --- a/src/components/Page/Page.scss +++ b/src/components/Page/Page.scss @@ -29,3 +29,10 @@ padding: 1.5em; } } + +.contributors__section, .interactive +{ + @media print { + display: none !important; + } +} \ No newline at end of file diff --git a/src/components/PageLinks/PageLinks.scss b/src/components/PageLinks/PageLinks.scss index 7f45b7ff1526..60624bdd51fc 100644 --- a/src/components/PageLinks/PageLinks.scss +++ b/src/components/PageLinks/PageLinks.scss @@ -2,6 +2,10 @@ @import 'functions'; .page-links { + @media print { + display: none !important; + } + position: absolute; display: none; top: 1.5em; diff --git a/src/content/_all.md b/src/content/_all.md new file mode 100644 index 000000000000..fb91d2979380 --- /dev/null +++ b/src/content/_all.md @@ -0,0 +1,262 @@ + + +# Comparison + +webpack is not the only module bundler out there. If you are choosing between using webpack or any of the bundlers below, here is a feature-by-feature comparison on how webpack fares against the current competition. + +| Feature | webpack/webpack | jrburke/requirejs | substack/node-browserify | jspm/jspm-cli | rollup/rollup | brunch/brunch | +|---------|-----------------|-------------------|--------------------------|---------------|---------------|---------------| +| Additional chunks are loaded on demand | __yes__ | __yes__ | no | [System.import](https://github.com/systemjs/systemjs/blob/master/docs/system-api.md#systemimportmodulename--normalizedparentname---promisemodule) | no | no | +| AMD `define` | __yes__ | __yes__ | [deamdify](https://github.com/jaredhanson/deamdify) | yes | [rollup-plugin-amd](https://github.com/piuccio/rollup-plugin-amd) | yes | +| AMD `require` | __yes__ | __yes__ | no | yes | no | yes | +| AMD `require` loads on demand | __yes__ | with manual configuration | no | yes | no | no | +| CommonJS `exports` | __yes__ | only wrapping in `define` | __yes__ | yes | [commonjs-plugin](https://github.com/rollup/rollup-plugin-commonjs) | yes | +| CommonJS `require` | __yes__ | only wrapping in `define` | __yes__ | yes | [commonjs-plugin](https://github.com/rollup/rollup-plugin-commonjs) | yes | +| CommonJS `require.resolve` | __yes__ | no | no | no | no | | +| Concat in require `require("./fi" + "le")` | __yes__ | no♦ | no | no | no | | +| Debugging support | __SourceUrl, SourceMaps__ | not required | SourceMaps | __SourceUrl, SourceMaps__ | __SourceUrl, SourceMaps__ | SourceMaps | +| Dependencies | 19MB / 127 packages | 11MB / 118 packages | __1.2MB / 1 package__ | 26MB / 131 packages | ?MB / 3 packages | | +| ES2015 `import`/`export` | __yes__ (webpack 2) | no | no | __yes__ | __yes__ | yes, via [es6 module transpiler](https://github.com/gcollazo/es6-module-transpiler-brunch) +| Expressions in require (guided) `require("./templates/" + template)` | __yes (all files matching included)__ | no♦ | no | no | no | no | +| Expressions in require (free) `require(moduleName)` | with manual configuration | no♦ | no | no | no | | +| Generate a single bundle | __yes__ | yes♦ | yes | yes | yes | yes | +| Indirect require `var r = require; r("./file")` | __yes__ | no♦ | no | no | no | | +| Load each file separate | no | yes | no | yes | no | no | +| Mangle path names | __yes__ | no | partial | yes | not required (path names are not included in the bundle) | no | +| Minimizing | terser | uglify, closure compiler | [uglifyify](https://github.com/hughsk/uglifyify) | yes | [uglify-plugin](https://github.com/TrySound/rollup-plugin-uglify) | [UglifyJS-brunch](https://github.com/brunch/uglify-js-brunch) +| Multi pages build with common bundle | with manual configuration | __yes__ | with manual configuration | with bundle arithmetic | no | no| +| Multiple bundles | __yes__ | with manual configuration | with manual configuration | yes | no | yes | +| Node.js built-in libs `require("path")` | __yes__ | no | __yes__ | __yes__ | [node-resolve-plugin](https://github.com/rollup/rollup-plugin-node-resolve) | | +| Other Node.js stuff | process, __dir/filename, global | - | process, __dir/filename, global | process, __dir/filename, global for cjs | global ([commonjs-plugin](https://github.com/rollup/rollup-plugin-commonjs)) | | +| Plugins | __yes__ | yes | __yes__ | yes | yes | yes | +| Preprocessing | __loaders, [transforms](https://github.com/webpack-contrib/transform-loader)__ | loaders | transforms | plugin translate | plugin transforms | compilers, optimizers | +| Replacement for browser | `web_modules`, `.web.js`, package.json field, alias config option | alias option | package.json field, alias option | package.json, alias option | no | | +| Requirable files | file system | __web__ | file system | through plugins | file system or through plugins | file system | +| Runtime overhead | __243B + 20B per module + 4B per dependency__ | 14.7kB + 0B per module + (3B + X) per dependency | 415B + 25B per module + (6B + 2X) per dependency | 5.5kB for self-executing bundles, 38kB for full loader and polyfill, 0 plain modules, 293B CJS, 139B ES2015 System.register before gzip | __none for ES2015 modules__ (other formats may have) | | +| Watch mode | yes | not required | [watchify](https://github.com/browserify/watchify) | not needed in dev | [rollup-watch](https://github.com/rollup/rollup-watch) | yes | + +♦ in production mode (opposite in development mode) + +X is the length of the path string + + +## Bundling vs. Loading + +It's important to note some key differences between _loading_ and _bundling_ modules. A tool like [SystemJS](https://github.com/systemjs/systemjs), which can be found under the hood of [JSPM](https://github.com/jspm/jspm-cli), is used to load and transpile modules at runtime in the browser. This differs significantly from webpack, where modules are transpiled (through "loaders") and bundled before hitting the browser. + +Each method has its advantages and disadvantages. Loading and transpiling modules at runtime can add a lot of overhead for larger sites and applications comprised of many modules. For this reason, SystemJS makes more sense for smaller projects where fewer modules are required. However, this may change a bit as [HTTP/2](https://http2.github.io/) will improve the speed at which files can be transferred from server to client. Note that HTTP/2 doesn't change anything about _transpiling_ modules, which will always take longer when done client-side. + + +# Branding Guidelines + +Here you can find __webpack__ project brand guidelines, assets, and license. See our official [media repository](https://github.com/webpack/media) for more information and to find the [license](https://github.com/webpack/media/blob/master/LICENSE) that governs this work. Click any of the images to download them. + + +## The Name + +webpack should __always__ be written in lower-case letters, even at the beginning of a sentence. + + +## Logo + +The webpack logo should be placed on a white background with enough space around it like this: + +webpack logo default with proper spacing on light background + +[svg](https://github.com/webpack/media/blob/master/logo/logo-on-white-bg.svg) | [png](https://github.com/webpack/media/blob/master/logo/logo-on-white-bg.png) | [jpg](https://github.com/webpack/media/blob/master/logo/logo-on-white-bg.jpg) + +Just double the size of the inner dark blue cube to get an idea how much space the logo should have. + +For dark backgrounds, you can use the negative version of the logo: + +
+ webpack logo default with proper spacing on light background +
+ +[svg](https://github.com/webpack/media/blob/master/logo/logo-on-dark-bg.svg) | [png](https://github.com/webpack/media/blob/master/logo/logo-on-dark-bg.png) | [jpg](https://github.com/webpack/media/blob/master/logo/logo-on-dark-bg.jpg) + +T> Please use the __icon + text__ whenever possible. + + +## Icon only + +__The icon is designed to be used in layout-constrained areas. As previously stated, please prefer icon + text.__ + +icon example + +[svg](https://github.com/webpack/media/blob/master/logo/icon.svg) | [png](https://github.com/webpack/media/blob/master/logo/icon.png) | [jpg](https://github.com/webpack/media/blob/master/logo/icon.jpg) + +Square-sized icon for bigger areas (like avatars or profile pictures): + +icon square big example + +[svg](https://github.com/webpack/media/blob/master/logo/icon-square-big.svg) | [png](https://github.com/webpack/media/blob/master/logo/icon-square-big.png) | [jpg](https://github.com/webpack/media/blob/master/logo/icon-square-big.jpg) + +Square-sized icon for smaller areas (like favicons): + +icon square small example + +[svg](https://github.com/webpack/media/blob/master/logo/icon-square-small.svg) | [png](https://github.com/webpack/media/blob/master/logo/icon-square-small.png) | [jpg](https://github.com/webpack/media/blob/master/logo/icon-square-small.jpg) + +T> For those of you following our guidelines and have gotten this far, we've made a special smaller size image used especially for custom emoji (like in a slack or gitter channel ;)) + +icon square small example + + +## Font + +We use the beautiful [Geomanist Medium](http://atipofoundry.com/fonts/geomanist) font from the extremely talented folks at the [Atipo Foundry](http://atipofoundry.com/) who provide the entire font family at a 'pay what you want' model. + + +## Color Palette + +The following colors are used throughout the site in various combinations and on our fancy clothing line launched with the help of [Open Collective](https://opencollective.com/) and [Threadless](https://medium.com/u/840563ee2a56) over at the [official webpack store](https://webpack.threadless.com/collections/the-final-release-collection/)! + +| Color Name | HEX Code | RGB Code | Sample +|---------------|---------------|-----------------------|------------------------------- +| Malibu: | HEX `#8dd6f9` | `rgb: 141, 214, 249` |
 
+| Denim: | HEX `#1d78c1` | `rgb: 29, 120, 193` |
 
+| Fiord: | HEX `#465E69` | `rgb: 70, 94, 105` |
 
+| Outer Space: | HEX `#2B3A42` | `rgb: 43, 58, 66` |
 
+| White: | HEX `#ffffff` | `rgb: 255, 255, 255` |
 
+| Concrete: | HEX `#f2f2f2` | `rgb: 242, 242, 242` |
 
+| Alto: | HEX `#dedede` | `rgb: 222, 222, 222` |
 
+| Dusty Gray: | HEX `#999999` | `rgb: 153, 153, 153` |
 
+| Dove Gray: | HEX `#666666` | `rgb: 102, 102, 102` |
 
+| Emperor: | HEX `#535353` | `rgb: 83, 83, 83` |
 
+| Mine Shaft: | HEX `#333333` | `rgb: 51, 51, 51` |
 
+ +In addition, you can grab the following file types directly from these links: + +[psd](https://raw.githubusercontent.com/webpack/media/master/design/webpack-palette.psd) | [png](https://raw.githubusercontent.com/webpack/media/master/design/webpack-palette.png) + | [ai](https://raw.githubusercontent.com/webpack/media/master/design/webpack-palette.ai) | [svg](https://raw.githubusercontent.com/webpack/media/master/design/webpack-palette.svg) + + +## License + +The logo and the brand name are __not MIT licensed__. Please check [our LICENSE](https://github.com/webpack/media/blob/master/LICENSE) for usage guidelines. + + +# Glossary + +This index lists common terms used throughout the webpack ecosystem. + + +## A + +- [__Asset__](/guides/asset-management/): This a general term for the images, fonts, media, and any other kind of files that are typically used in websites and other applications. These typically end up as individual files within the [output](/glossary#o) but can also be inlined via things like the [style-loader](/loaders/style-loader) or [url-loader](/loaders/url-loader). + + +## B + +- [__Bundle__](/guides/getting-started/#creating-a-bundle): Produced from a number of distinct modules, bundles contain the final versions of source files that have already undergone the loading and compilation process. +- [__Bundle Splitting__](/guides/code-splitting): This process offers one way of optimizing a build, allowing webpack to generate multiple bundles for a single application. As a result, each bundle can be isolated from changes effecting others, reducing the amount of code that needs to be republished and therefore re-downloaded by the client and taking advantage of browser caching. + + +## C + +- __Chunk__: This webpack-specific term is used internally to manage the bundling process. Bundles are composed out of chunks, of which there are several types (e.g. entry and child). Typically, _chunks_ directly correspond with the output _bundles_ however, there are some configurations that don't yield a one-to-one relationship. +- [__Code Splitting__](/guides/code-splitting/): Refers to dividing your code into various bundles/chunks which you can then load on demand instead of loading a single bundle containing everything. +- [__Configuration__](/concepts/configuration/): webpack config file is a plain old JavaScript file that exports an object. This object is then processed by webpack based upon its defined properties. + + +## D + +- [__Dependency Graph__](/concepts/dependency-graph): Any time one file depends on another, webpack treats this as a _dependency_. Starting from an entry point(s), webpack recursively builds a dependency graph that includes every module/asset your application needs. + + +## E + +- [__Entry Point__](/concepts/entry-points): The entry point tells webpack where to start and follows the graph of dependencies to know what to bundle. You can think of your application's entry point(s) as the __contextual root(s)__ of what you want bundled. + + +## F + +## G + +## H + +- [__Hot Module Replacement (HMR)__](/concepts/hot-module-replacement): A process that exchanges, adds, or removes `modules` while an application is running without a full page reload. + + +## I + +## J + +## K + +## L + +- [__Loaders__](/concepts/loaders): Transformations that are applied on the source code of a module. They allow you to pre-process files as you `require()` or "load" them. Similar to a 'task-runner'. + + +## M + +- [__Module__](/concepts/modules): Discrete chunks of functionality that provide a smaller surface area than a full program. Well-written modules provide solid abstractions and encapsulation boundaries which make up a coherent design and clear purpose. +- [__Module Resolution__](/concepts/module-resolution/): A module can be required as a dependency from another module and a resolver is a library which helps in locating a module by its absolute path.. Modules are searched for inside all directories specified in `resolve.modules`. + + +## N + +## O + +- [__Output__](/concepts/output): Option(s) specifying where to output the compiled files to disk. + > _Note, that while there can be multiple entry points, only one output configuration is specified._ + + +## P + +- [__Plugin__](/concepts/plugins): A JavaScript object that has an `apply` property. This `apply` property is called by the webpack compiler, giving access to the entire compilation lifecycle. These packages will typically extend compilation functionality in one way or another. + + +## Q + +## R + +- [__Request__](/guides/dependency-management/): Refers to the expression in the require/import statement, e.g. _require("./template/" + name + ".ejs")_, the request is _"./template/" + name + ".ejs"_. + +## S + +## T + +- [__Target__](/configuration/target/): User configured deployment target(s) [listed here](/configuration/target/) to compile for a specific environment like the browser, NodeJS, or Electron. +- [__Tree Shaking__](/guides/tree-shaking/): Unused/Excess code elimination, or more precisely, live code importing. Compilers like webpack will accomplish this by analyzing the various kinds `import` statements and usage of the imported code to determine what parts of dependencies are actually being utilized, dropping parts of the "tree" that are not. + + +## U + +## V + +- [__Vendor Entry Point__](/concepts/entry-points/#separate-app-and-vendor-entries): Create dependency graphs starting at both `app.js` and `vendors.js`. These graphs are completely separate and independent of each other to allow leverage of `CommonsChunkPlugin` and extract any vendor references from your app bundle into your vendor bundle. Helps achieve a common pattern in webpack known as [long-term vendor-caching](/guides/caching/). + + +## W + +- [__webpack__](/): A highly configurable [module](/concepts/modules) bundler for modern JavaScript applications + + +## X + +## Y + +## Z + + +# License + +## webpack + +webpack is [MIT licensed](https://github.com/webpack/webpack/blob/master/LICENSE). + +## webpack logo and icon + +The webpack logo and icon are under a different license which can be +found [here](https://github.com/webpack/media). + +## webpack documentation + +The content on [https://webpack.js.org/](https://webpack.js.org/) is available under [Creative Commons BY 4.0](https://creativecommons.org/licenses/by/4.0/) license meaning attribution is required should you use the content elsewhere. + +## webpack code samples + +The code samples use [CC0 1.0 Universal (CC0 1.0) (Public Domain)](https://creativecommons.org/publicdomain/zero/1.0/) and you are free to use them as you like. diff --git a/src/content/api/_api_all.md b/src/content/api/_api_all.md new file mode 100644 index 000000000000..d54e6da2b86f --- /dev/null +++ b/src/content/api/_api_all.md @@ -0,0 +1,3189 @@ + + +# Compiler Hooks + +The `Compiler` module is the main engine that creates a compilation instance +with all the options passed through the [CLI](/api/cli) or [Node API](/api/node). It extends the +`Tapable` class in order to register and call plugins. Most user facing plugins +are first registered on the `Compiler`. + +T> This module is exposed as `webpack.Compiler` and can be used directly. See +[this example](https://github.com/pksjce/webpack-internal-examples/tree/master/compiler-example) +for more information. + +When developing a plugin for webpack, you might want to know where each hook is called. To learn this, search for `hooks..call` across the webpack source + + +## Watching + +The `Compiler` supports [watching](/api/node/#watching) which monitors the file +system and recompiles as files change. When in watch mode, the compiler will +emit the additional events such as `watchRun`, `watchClose`, and `invalid`. +This is typically used in [development](/guides/development), usually under +the hood of tools like `webpack-dev-server`, so that the developer doesn't +need to re-compile manually every time. Watch mode can also be entered via the +[CLI](/api/cli/#watch-options). + + +## Hooks + +The following lifecycle hooks are exposed by the `compiler` and can be accessed +as such: + +``` js +compiler.hooks.someHook.tap(/* ... */); +``` + +Depending on the hook type, `tapAsync` and `tapPromise` may also be available. + +For the description of hook types, see [the Tapable docs](https://github.com/webpack/tapable#hook-types). + + +### `entryOption` + +`SyncBailHook` + +Executes a plugin after [the `entry` configuration](https://webpack.js.org/configuration/entry-context/#entry) from webpack options has been processed. + + +### `afterPlugins` + +`SyncHook` + +Runs a plugin after setting up initial set of plugins. + +Parameters: `compiler` + + +### `afterResolvers` + +`SyncHook` + +Executes a plugin after resolver setup is complete. + +Parameters: `compiler` + + +### `environment` + +`SyncHook` + +Runs a plugin before the environment is prepared. + + +### `afterEnvironment` + +`SyncHook` + +Executes a plugin a environment setup is complete. + + +### `beforeRun` + +`AsyncSeriesHook` + +Adds a hook right before `compiler.run()` is executed. + +Parameters: `compiler` + + +### `run` + +`AsyncSeriesHook` + +Hook into the compiler before it begins reading records. + +Parameters: `compiler` + + +### `watchRun` + +`AsyncSeriesHook` + +Executes a plugin during watch mode after a new compilation is triggered +but before the compilation is actually started. + +Parameters: `compiler` + + +### `normalModuleFactory` + +`SyncHook` + +Runs a plugin after a `NormalModuleFactory` is created. + +Parameters: `normalModuleFactory` + + +### `contextModuleFactory` + +Runs a plugin after a `ContextModuleFactory` is created. + +Parameters: `contextModuleFactory` + + +### `beforeCompile` + +`AsyncSeriesHook` + +Executes a plugin after compilation parameters are created. + +Parameters: `compilationParams` + + +### `compile` + +`SyncHook` + +Hook into the compiler before a new compilation is created. + +Parameters: `compilationParams` + + +### `thisCompilation` + +`SyncHook` + +Executed before emitting the `compilation` event (see below). + +Parameters: `compilation` + + +### `compilation` + +`SyncHook` + +Runs a plugin after a compilation has been created. + +Parameters: `compilation` + + +### `make` + +`AsyncParallelHook` + +... + +Parameters: `compilation` + + +### `afterCompile` + +`AsyncSeriesHook` + +... + +Parameters: `compilation` + + +### `shouldEmit` + +`SyncBailHook` + +Can return true/false at this point + +Parameters: `compilation` + + +### `emit` + +`AsyncSeriesHook` + +Before emitting assets to output dir + +Parameters: `compilation` + + +### `afterEmit` + +`AsyncSeriesHook` + +After emitting assets to output dir + +Parameters: `compilation` + + +### `done` + +`AsyncSeriesHook` + +Compilation has completed. + +Parameters: `stats` + + +### `failed` + +`SyncHook` + +Compilation has failed. + +Parameters: `error` + + +### `invalid` + +`SyncHook` + +Watch compilation has been invalidated. + +Parameters: `fileName`, `changeTime` + + +### `watchClose` + +`SyncHook` + +Watch mode has stopped. + + +# Introduction + +A variety of interfaces are available to customize the compilation process. +Some features overlap between interfaces, e.g. a configuration option may be +available via a CLI flag, while others exist only through a single interface. +The following high-level information should get you started. + + +## CLI + +The Command Line Interface (CLI) to configure and interact with your build. It +is especially useful in the case of early prototyping and profiling. For the +most part, the CLI is simply used to kick off the process using a configuration +file and a few flags (e.g. `--env`). + +[Learn more about the CLI!](/api/cli) + + +## Module + +When processing modules with webpack, it is important to understand the +different module syntaxes -- specifically the [methods](/api/module-methods) +and [variables](/api/module-variables) -- that are supported. + +[Learn more about modules!](/api/module-methods) + + +## Node + +While most users can get away with just using the CLI along with a +configuration file, more fine-grained control of the compilation can be +achieved via the Node interface. This includes passing multiple configurations, +programmatically running or watching, and collecting stats. + +[Learn more about the Node API!](/api/node) + + +## Loaders + +Loaders are transformations that are applied to the source code of a module. +They are written as functions that accept source code as a parameter and return +a new version of that code with transformations applied. + +[Learn more about loaders!](/api/loaders) + + +## Plugins + +The plugin interface allows users to tap directly into the compilation process. +Plugins can register handlers on lifecycle hooks that run at different points +throughout a compilation. When each hook is executed, the plugin will have full +access to the current state of the compilation. + +[Learn more about plugins!](/api/plugins) + + +# Command Line Interface + +For proper usage and easy distribution of this configuration, webpack can be configured with `webpack.config.js`. Any parameters sent to the CLI will map to a corresponding parameter in the config file. + +Read the [installation guide](/guides/installation) if you don't already have webpack and CLI installed. + + +## Usage with config file + +```sh +webpack [--config webpack.config.js] +``` + +See [configuration](/configuration) for the options in the configuration file. + + +## Usage without config file + +```sh +webpack [] -o +``` + +__``__ + +A filename or a set of named filenames which act as the entry point to build your project. You can pass multiple entries (every entry is loaded on startup). If you pass a pair in the form `=` you can create an additional entry point. It will be mapped to the configuration option `entry`. + +__``__ + +A path and filename for the bundled file to be saved in. It will be mapped to the configuration options `output.path` and `output.filename`. + +__Example__ + +If your project structure is as follows - + +```bash +. +├── dist +├── index.html +└── src + ├── index.js + ├── index2.js + └── others.js +``` + +```bash +webpack src/index.js -o dist/bundle.js +``` + +This will bundle your source code with entry as `index.js` and the output bundle file will have a path of `dist` and the filename will be `bundle.js` + +```bash + | Asset | Size | Chunks | Chunk Names | + |-----------|---------|-------------|-------------| + | bundle.js | 1.54 kB | 0 [emitted] | index | + [0] ./src/index.js 51 bytes {0} [built] + [1] ./src/others.js 29 bytes {0} [built] +``` + +```bash +webpack index=./src/index.js entry2=./src/index2.js dist/bundle.js +``` + +This will form the bundle with both the files as separate entry points. + +```bash + | Asset | Size | Chunks | Chunk Names | + |-----------|---------|---------------|---------------| + | bundle.js | 1.55 kB | 0,1 [emitted] | index, entry2 | + [0] ./src/index.js 51 bytes {0} [built] + [0] ./src/index2.js 54 bytes {1} [built] + [1] ./src/others.js 29 bytes {0} {1} [built] +``` + + +### Common Options + +W> Note that Command Line Interface has a higher precedence for the arguments you use it with than your configuration file. For instance, if you pass [`--mode="production"`](/concepts/mode/#usage) to webpack CLI and your configuration file uses `development`, `production` will be used. + +__List all of the options available on the cli__ + +```bash +webpack --help +webpack -h +``` + +__Build source using a config file__ + +Specifies a different [configuration](/configuration) file to pick up. Use this if you want to specify something different than `webpack.config.js`, which is the default. + +```bash +webpack --config example.config.js +``` + +__Print result of webpack as a JSON__ + +```bash +webpack --json +webpack --json > stats.json +``` + +In every other case, webpack prints out a set of stats showing bundle, chunk and timing details. Using this option the output can be a JSON object. This response is accepted by webpack's [analyse tool](https://webpack.github.io/analyse/), or chrisbateman's [webpack-visualizer](https://chrisbateman.github.io/webpack-visualizer/), or th0r's [webpack-bundle-analyzer](https://github.com/webpack-contrib/webpack-bundle-analyzer). The analyse tool will take in the JSON and provide all the details of the build in graphical form. + +### Environment Options + +When the webpack configuration [exports a function](/configuration/configuration-types#exporting-a-function), an "environment" may be passed to it. + +```bash +webpack --env.production # sets env.production == true +webpack --env.platform=web # sets env.platform == "web" +``` + +The `--env` argument accepts various syntaxes: + +Invocation | Resulting environment +---------------------------------------- | --------------------------- +`webpack --env prod` | `"prod"` +`webpack --env.prod` | `{ prod: true }` +`webpack --env.prod=1` | `{ prod: 1 }` +`webpack --env.prod=foo` | `{ prod: "foo" }` +`webpack --env.prod --env.min` | `{ prod: true, min: true }` +`webpack --env.prod --env min` | `[{ prod: true }, "min"]` +`webpack --env.prod=foo --env.prod=bar` | `{prod: [ "foo", "bar" ]}` + +T> See the [environment variables](/guides/environment-variables) guide for more information on its usage. + +### Config Options + +Parameter | Explanation | Input type | Default +------------------------- | ------------------------------------------- | ---------- | ------------------ +`--config` | Path to the config file | string | webpack.config.js or webpackfile.js +`--config-register, -r` | Preload one or more modules before loading the webpack configuration | array | +`--config-name` | Name of the config to use | string | +`--env` | Environment passed to the config, when it is a function | | +`--mode` | Mode to use, either "development" or "production" | string | + +### Output Options + +This set of options allows you to manipulate certain [output](/configuration/output) parameters of your build. + +Parameter | Explanation | Input type | Default +------------------------- | ------------------------------------------- | ---------- | ------------------ +`--output-chunk-filename` | The output filename for additional chunks | string | filename with [id] instead of [name] or [id] prefixed +`--output-filename` | The output filename of the bundle | string | [name].js +`--output-jsonp-function` | The name of the JSONP function used for chunk loading | string | webpackJsonp +`--output-library` | Expose the exports of the entry point as library | string | +`--output-library-target` | The type for exposing the exports of the entry point as library | string | var +`--output-path` | The output path for compilation assets | string | Current directory +`--output-pathinfo` | Include a comment with the request for every dependency | boolean | false +`--output-public-path` | The public path for the assets | string | / +`--output-source-map-filename` | The output filename for the SourceMap | string | [name].map or [outputFilename].map +`--build-delimiter` | Display custom text after build output | string | Default string is null. You could provide a string such as `=== Build done ===` + + +#### Example Usage + +```bash +webpack index=./src/index.js index2=./src/index2.js --output-path='./dist' --output-filename='[name][hash].bundle.js' + +| Asset | Size | Chunks | Chunk Names | +|--------------------------------------|---------|-------------|---------------| +| index2740fdca26e9348bedbec.bundle.js | 2.6 kB | 0 [emitted] | index2 | +| index740fdca26e9348bedbec.bundle.js | 2.59 kB | 1 [emitted] | index | + [0] ./src/others.js 29 bytes {0} {1} [built] + [1] ./src/index.js 51 bytes {1} [built] + [2] ./src/index2.js 54 bytes {0} [built] +``` + +```bash +webpack.js index=./src/index.js index2=./src/index2.js --output-path='./dist' --output-filename='[name][hash].bundle.js' --devtool source-map --output-source-map-filename='[name]123.map' + +| Asset | Size | Chunks | Chunk Names | +|--------------------------------------|---------|-------------|---------------| +| index2740fdca26e9348bedbec.bundle.js | 2.76 kB | 0 [emitted] | index2 | +| index740fdca26e9348bedbec.bundle.js | 2.74 kB | 1 [emitted] | index | +| index2123.map | 2.95 kB | 0 [emitted] | index2 | +| index123.map | 2.95 kB | 1 [emitted] | index | + [0] ./src/others.js 29 bytes {0} {1} [built] + [1] ./src/index.js 51 bytes {1} [built] + [2] ./src/index2.js 54 bytes {0} [built] +``` + + +### Debug Options + +This set of options allows you to better debug the application containing assets compiled with webpack + +Parameter | Explanation | Input type | Default value +------------ | ------------------------------------------------ | ---------- | ------------- +`--debug` | Switch loaders to debug mode | boolean | false +`--devtool` | Define [source map type](/configuration/devtool/) for the bundled resources | string | - +`--progress` | Print compilation progress in percentage | boolean | false +`--display-error-details` | Display details about errors | boolean | false + +### Module Options + +These options allow you to bind [modules](/configuration/module/) as allowed by webpack + +Parameter | Explanation | Usage +-------------------- | -------------------------------------- | ---------------- +`--module-bind` | Bind a file extension to a loader | `--module-bind js=babel-loader` +`--module-bind-post` | Bind a file extension to a post loader | +`--module-bind-pre` | Bind a file extension to a pre loader | + + +### Watch Options + +These options makes the build [watch](/configuration/watch/) for changes in files of the dependency graph and perform the build again. + +Parameter | Explanation +------------------------- | ---------------------- +`--watch`, `-w` | Watch the filesystem for changes +`--watch-aggregate-timeout` | Timeout for gathering changes while watching +`--watch-poll` | The polling interval for watching (also enable polling) +`--watch-stdin`, `--stdin` | Exit the process when stdin is closed + + +### Optimize Options + +These options allow you to manipulate optimisations for a production build using webpack + +Parameter | Explanation | Plugin Used +--------------------------- | -------------------------------------------------------|---------------------- +`--optimize-max-chunks` | Try to keep the chunk count below a limit | [LimitChunkCountPlugin](/plugins/limit-chunk-count-plugin) +`--optimize-min-chunk-size` | Try to keep the chunk size above a limit | [MinChunkSizePlugin](/plugins/min-chunk-size-plugin) +`--optimize-minimize` | Minimize javascript and switches loaders to minimizing | [TerserPlugin](/plugins/terser-webpack-plugin/) & [LoaderOptionsPlugin](/plugins/loader-options-plugin/) + + +### Resolve Options + +These allow you to configure the webpack [resolver](/configuration/resolve/) with aliases and extensions. + +Parameter | Explanation | Example +---------------------- | ------------------------------------------------------- | ------------- +`--resolve-alias` | Setup a module alias for resolving | --resolve-alias jquery-plugin=jquery.plugin +`--resolve-extensions` | Setup extensions that should be used to resolve modules | --resolve-extensions .es6 .js .ts +`--resolve-loader-alias` | Minimize javascript and switches loaders to minimizing | + + +### Stats Options + +These options allow webpack to display various [stats](/configuration/stats/) and style them differently in the console output. + +Parameter | Explanation | Type +-------------------------------- | ------------------------------------------------------------------ | ------- +`--color`, `--colors` | Force colors on the console [default: enabled for TTY output only] | boolean +`--no-color`, `--no-colors` | Force no colors on the console | boolean +`--display` | Select [display preset](/configuration/stats) (verbose, detailed, normal, minimal, errors-only, none; since webpack 3.0.0) | string +`--display-cached` | Display also cached modules in the output | boolean +`--display-cached-assets` | Display also cached assets in the output | boolean +`--display-chunks` | Display chunks in the output | boolean +`--display-depth` | Display distance from entry point for each module | boolean +`--display-entrypoints` | Display entry points in the output | boolean +`--display-error-details` | Display details about errors | boolean +`--display-exclude` | Exclude modules in the output | boolean +`--display-max-modules` | Sets the maximum number of visible modules in output | number +`--display-modules` | Display even excluded modules in the output | boolean +`--display-optimization-bailout` | Scope hoisting fallback trigger (since webpack 3.0.0) | boolean +`--display-origins` | Display origins of chunks in the output | boolean +`--display-provided-exports` | Display information about exports provided from modules | boolean +`--display-reasons` | Display reasons about module inclusion in the output | boolean +`--display-used-exports` | Display information about used exports in modules (Tree Shaking) | boolean +`--hide-modules` | Hides info about modules | boolean +`--sort-assets-by` | Sorts the assets list by property in asset | string +`--sort-chunks-by` | Sorts the chunks list by property in chunk | string +`--sort-modules-by` | Sorts the modules list by property in module | string +`--verbose` | Show more details | boolean + + +### Advanced Options + +Parameter | Explanation | Usage +----------------- | ---------------------------------------- | ----- +`--bail` | Abort the compilation on first error | +`--cache` | Enable in memory caching [Enabled by default for watch] | `--cache=false` +`--define` | Define any free variable, see [shimming](/guides/shimming) | `--define process.env.NODE_ENV="'development'"` +`--hot` | Enables [Hot Module Replacement](/concepts/hot-module-replacement) | `--hot=true` +`--labeled-modules` | Enables labeled modules [Uses LabeledModulesPlugin] | +`--plugin` | Load this [plugin](/configuration/plugins/) | +`--prefetch` | Prefetch the particular file | `--prefetch=./files.js` +`--provide` | Provide these modules as globals, see [shimming](/guides/shimming) | `--provide jQuery=jquery` +`--records-input-path` | Path to the records file (reading) | +`--records-output-path` | Path to the records file (writing) | +`--records-path` | Path to the records file | +`--target` | The [targeted](/configuration/target/) execution environment | `--target='node'` + +### Shortcuts + +Shortcut | Replaces +---------|---------------------------- +-d | `--debug --devtool cheap-module-eval-source-map --output-pathinfo` +-p | `--optimize-minimize --define process.env.NODE_ENV="production"`, see [building for production](/guides/production) + +### Profiling + +The `--profile` option captures timing information for each step of the compilation and includes this in the output. + +```bash +webpack --profile + +⋮ +[0] ./src/index.js 90 bytes {0} [built] + factory:22ms building:16ms = 38ms +``` + +For each module, the following details are included in the output as applicable: + +- `factory`: time to collect module metadata (e.g. resolving the filename) +- `building`: time to build the module (e.g. loaders and parsing) +- `dependencies`: time to identify and connect the module’s dependencies + +Paired with `--progress`, `--profile` gives you an in depth idea of which step in the compilation is taking how long. This can help you optimise your build in a more informed manner. + +```bash +webpack --progress --profile + +30ms building modules +1ms sealing +1ms optimizing +0ms basic module optimization +1ms module optimization +1ms advanced module optimization +0ms basic chunk optimization +0ms chunk optimization +1ms advanced chunk optimization +0ms module and chunk tree optimization +1ms module reviving +0ms module order optimization +1ms module id optimization +1ms chunk reviving +0ms chunk order optimization +1ms chunk id optimization +10ms hashing +0ms module assets processing +13ms chunk assets processing +1ms additional chunk assets processing +0ms recording +0ms additional asset processing +26ms chunk asset optimization +1ms asset optimization +6ms emitting +⋮ +``` + + +# Compilation Hooks + +The `Compilation` module is used by the `Compiler` to create new compilations +(or builds). A `compilation` instance has access to all modules and their +dependencies (most of which are circular references). It is the literal +compilation of all the modules in the dependency graph of an application. +During the compilation phase, modules are loaded, sealed, optimized, chunked, +hashed and restored. + +The `Compilation` class also extends `Tapable` and provides the following +lifecycle hooks. They can be tapped the same way as compiler hooks: + +``` js +compilation.hooks.someHook.tap(/* ... */); +``` + +As with the `compiler`, `tapAsync` and `tapPromise` may also be available +depending on the type of hook. + + +### `buildModule` + +`SyncHook` + +Triggered before a module build has started. + +Parameters: `module` + + +### `rebuildModule` + +`SyncHook` + +Fired before rebuilding a module. + +Parameters: `module` + + +### `failedModule` + +`SyncHook` + +Run when a module build has failed. + +Parameters: `module` `error` + + +### `succeedModule` + +`SyncHook` + +Executed when a module has been built successfully. + +Parameters: `module` + + +### `finishModules` + +`SyncHook` + +All modules have been built. + +Parameters: `modules` + + +### `finishRebuildingModule` + +`SyncHook` + +A module has been rebuilt. + +Parameters: `module` + + +### `seal` + +`SyncHook` + +Fired when the compilation stops accepting new modules. + + +### `unseal` + +`SyncHook` + +Fired when a compilation begins accepting new modules. + + +### `optimizeDependenciesBasic` + +`SyncBailHook` + +... + +Parameters: `modules` + + +### `optimizeDependencies` + +`SyncBailHook` + +Fired at the beginning of dependency optimization. + +Parameters: `modules` + + +### `optimizeDependenciesAdvanced` + +`SyncBailHook` + +... + +Parameters: `modules` + + +### `afterOptimizeDependencies` + +`SyncHook` + +... + +Parameters: `modules` + + +### `optimize` + +`SyncHook` + +Triggered at the beginning of the optimization phase. + + +### `optimizeModulesBasic` + +`SyncBailHook` + +... + +Parameters: `modules` + + +### `optimizeModules` + +`SyncBailHook` + +... + +Parameters: `modules` + + +### `optimizeModulesAdvanced` + +`SyncBailHook` + +... + +Parameters: `modules` + + +### `afterOptimizeModules` + +`SyncHook` + +... + +Parameters: `modules` + + +### `optimizeChunksBasic` + +`SyncBailHook` + +... + +Parameters: `chunks` + + +### `optimizeChunks` + +`SyncBailHook` + +Optimize the chunks. + +Parameters: `chunks` + + +### `optimizeChunksAdvanced` + +`SyncBailHook` + +... + +Parameters: `chunks` + + +### `afterOptimizeChunks` + +`SyncHook` + +Fired after chunk optimization has completed. + +Parameters: `chunks` + + +### `optimizeTree` + +`AsyncSeriesHook` + +Optimize the dependency tree asynchronously. + +Parameters: `chunks` `modules` + + +### `afterOptimizeTree` + +`SyncHook` + +... + +Parameters: `chunks` `modules` + + +### `optimizeChunkModulesBasic` + +`SyncBailHook` + +... + +Parameters: `chunks` `modules` + + +### `optimizeChunkModules` + +`SyncBailHook` + +... + +Parameters: `chunks` `modules` + + +### `optimizeChunkModulesAdvanced` + +`SyncBailHook` + +... + +Parameters: `chunks` `modules` + + +### `afterOptimizeChunkModules` + +`SyncHook` + +... + +Parameters: `chunks` `modules` + + +### `shouldRecord` + +`SyncBailHook` + +... + + +### `reviveModules` + +`SyncHook` + +Restore module information from records. + +Parameters: `modules` `records` + + +### `optimizeModuleOrder` + +`SyncHook` + +Sort the modules in from most to least important. + +Parameters: `modules` + + +### `advancedOptimizeModuleOrder` + +`SyncHook` + +... + +Parameters: `modules` + + +### `beforeModuleIds` + +`SyncHook` + +... + +Parameters: `modules` + + +### `moduleIds` + +`SyncHook` + +... + +Parameters: `modules` + + +### `optimizeModuleIds` + +`SyncHook` + +... + +Parameters: `chunks` + + +### `afterOptimizeModuleIds` + +`SyncHook` + +... + +Parameters: `chunks` + + +### `reviveChunks` + +`SyncHook` + +Restore chunk information from records. + +Parameters: `modules` `records` + + +### `optimizeChunkOrder` + +`SyncHook` + +Sort the chunks in from most to least important. + +Parameters: `chunks` + + +### `beforeOptimizeChunkIds` + +`SyncHook` + +Fired before chunk `id` optimization. + +Parameters: `chunks` + + +### `optimizeChunkIds` + +`SyncHook` + +Optimize the `id` of each chunk. + +Parameters: `chunks` + + +### `afterOptimizeChunkIds` + +`SyncHook` + +Triggered after chunk `id` optimization has finished. + +Parameters: `chunks` + + +### `recordModules` + +`SyncHook` + +Store module info to the records. + +Parameters: `modules` `records` + + +### `recordChunks` + +`SyncHook` + +Store chunk info to the records. + +Parameters: `chunks` `records` + + +### `beforeHash` + +`SyncHook` + +Before the compilation is hashed. + + +### `afterHash` + +`SyncHook` + +After the compilation is hashed. + + +### `recordHash` + +`SyncHook` + +... + +Parameters: `records` + + +### `record` + +`SyncHook` + +Store information about the `compilation` to the `records`. + +Parameters: `compilation` `records` + + +### `beforeModuleAssets` + +`SyncHook` + +... + + +### `shouldGenerateChunkAssets` + +`SyncBailHook` + +... + + +### `beforeChunkAssets` + +`SyncHook` + +Before creating the chunk assets. + + +### `additionalChunkAssets` + +`SyncHook` + +Create additional assets for the chunks. + +Parameters: `chunks` + + +### `records` + +`SyncHook` + +... + +Parameters: `compilation` `records` + + +### `additionalAssets` + +`AsyncSeriesHook` + +Create additional assets for the compilation. This hook can be used to download +an image, for example: + +``` js +compilation.hooks.additionalAssets.tapAsync('MyPlugin', callback => { + download('https://img.shields.io/npm/v/webpack.svg', function(resp) { + if(resp.status === 200) { + compilation.assets['webpack-version.svg'] = toAsset(resp); + callback(); + } else { + callback(new Error('[webpack-example-plugin] Unable to download the image')); + } + }); +}); +``` + + +### `optimizeChunkAssets` + +`AsyncSeriesHook` + +Optimize any chunk assets. The assets are stored in `compilation.assets`. A +`Chunk` has a property `files` which points to all files created by a chunk. +Any additional chunk assets are stored in `compilation.additionalChunkAssets`. + +Parameters: `chunks` + +Here's an example that simply adds a banner to each chunk. + +``` js +compilation.hooks + .optimizeChunkAssets + .tapAsync('MyPlugin', (chunks, callback) => { + chunks.forEach(chunk => { + chunk.files.forEach(file => { + compilation.assets[file] = new ConcatSource( + '\/**Sweet Banner**\/', + '\n', + compilation.assets[file] + ); + }); + }); + + callback(); + }); +``` + + +### `afterOptimizeChunkAssets` + +`SyncHook` + +The chunk assets have been optimized. + +Parameters: `chunks` + +Here's an example plugin from [@boopathi](https://github.com/boopathi) that outputs exactly what went into each chunk. + +``` js +compilation.hooks.afterOptimizeChunkAssets.tap('MyPlugin', chunks => { + chunks.forEach(chunk => { + console.log({ + id: chunk.id, + name: chunk.name, + includes: chunk.modules.map(module => module.request) + }); + }); +}); +``` + + +### `optimizeAssets` + +`AsyncSeriesHook` + +Optimize all assets stored in `compilation.assets`. + +Parameters: `assets` + + +### `afterOptimizeAssets` + +`SyncHook` + +The assets has been optimized. + +Parameters: `assets` + + +### `needAdditionalSeal` + +`SyncBailHook` + +... + + +### `afterSeal` + +`AsyncSeriesHook` + +... + + +### `chunkHash` + +`SyncHook` + +... + +Parameters: `chunk` `chunkHash` + + +### `moduleAsset` + +`SyncHook` + +An asset from a module was added to the compilation. + +Parameters: `module` `filename` + + +### `chunkAsset` + +`SyncHook` + +An asset from a chunk was added to the compilation. + +Parameters: `chunk` `filename` + + +### `assetPath` + +`SyncWaterfallHook` + +... + +Parameters: `filename` `data` + + +### `needAdditionalPass` + +`SyncBailHook` + +... + + +### `childCompiler` + +`SyncHook` + +... + +Parameters: `childCompiler` `compilerName` `compilerIndex` + + +### `normalModuleLoader` + +`SyncHook` + +The normal module loader is the function that actually loads all the modules +in the module graph (one-by-one). + +Parameters: `loaderContext` `module` + +### `dependencyReference` + +`SyncWaterfallHook` + +`Compilation.hooks.dependencyReference(depRef, dependency, module)` allows to change the references reported by dependencies. + +Parameters: `depRef` `dependency` `module` + + +# Module Methods + +This section covers all methods available in code compiled with webpack. When using webpack to bundle your application, you can pick from a variety of module syntax styles including [ES6](https://en.wikipedia.org/wiki/ECMAScript#6th_Edition_-_ECMAScript_2015), [CommonJS](https://en.wikipedia.org/wiki/CommonJS), and [AMD](https://en.wikipedia.org/wiki/Asynchronous_module_definition). + +W> While webpack supports multiple module syntaxes, we recommend following a single syntax for consistency and to avoid odd behaviors/bugs. Here's [one example](https://github.com/webpack/webpack.js.org/issues/552) of mixing ES6 and CommonJS, however there are surely others. + + +## ES6 (Recommended) + +Version 2 of webpack supports ES6 module syntax natively, meaning you can use `import` and `export` without a tool like babel to handle this for you. Keep in mind that you will still probably need babel for other ES6+ features. The following methods are supported by webpack: + + +### `import` + +Statically `import` the `export`s of another module. + +``` javascript +import MyModule from './my-module.js'; +import { NamedExport } from './other-module.js'; +``` + +W> The keyword here is __statically__. Normal `import` statement cannot be used dynamically within other logic or contain variables. See the [spec](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) for more information and `import()` below for dynamic usage. + + +### `export` + +Export anything as a `default` or named export. + +``` javascript +// Named exports +export var Count = 5; +export function Multiply(a, b) { + return a * b; +} + +// Default export +export default { + // Some data... +}; +``` + + +### `import()` + +`import('path/to/module') -> Promise` + +Dynamically load modules. Calls to `import()` are treated as split points, meaning the requested module and it's children are split out into a separate chunk. + +T> The [ES2015 Loader spec](https://whatwg.github.io/loader/) defines `import()` as method to load ES2015 modules dynamically on runtime. + +``` javascript +if ( module.hot ) { + import('lodash').then(_ => { + // Do something with lodash (a.k.a '_')... + }); +} +``` + +W> This feature relies on [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) internally. If you use `import()` with older browsers, remember to shim `Promise` using a polyfill such as [es6-promise](https://github.com/stefanpenner/es6-promise) or [promise-polyfill](https://github.com/taylorhakes/promise-polyfill). + +The spec for `import` doesn't allow control over the chunk's name or other properties as "chunks" are only a concept within webpack. Luckily webpack allows some special parameters via comments so as to not break the spec: + +``` js +// Single target +import( + /* webpackChunkName: "my-chunk-name" */ + /* webpackMode: "lazy" */ + 'module' +); + +// Multiple possible targets +import( + /* webpackInclude: /\.json$/ */ + /* webpackExclude: /\.noimport\.json$/ */ + /* webpackChunkName: "my-chunk-name" */ + /* webpackMode: "lazy" */ + `./locale/${language}` +); +``` + +```js +import(/* webpackIgnore: true */ 'ignored-module.js'); +``` + +`webpackIgnore`: Disables dynamic import parsing when set to `true`. + +W> Note that setting `webpackIgnore` to `true` opts out of code splitting. + +`webpackChunkName`: A name for the new chunk. Since webpack 2.6.0, the placeholders `[index]` and `[request]` are supported within the given string to an incremented number or the actual resolved filename respectively. + +`webpackMode`: Since webpack 2.6.0, different modes for resolving dynamic imports can be specified. The following options are supported: + +- `"lazy"` (default): Generates a lazy-loadable chunk for each `import()`ed module. +- `"lazy-once"`: Generates a single lazy-loadable chunk that can satisfy all calls to `import()`. The chunk will be fetched on the first call to `import()`, and subsequent calls to `import()` will use the same network response. Note that this only makes sense in the case of a partially dynamic statement, e.g. ``import(`./locales/${language}.json`)``, where there are multiple module paths that could potentially be requested. +- `"eager"`: Generates no extra chunk. All modules are included in the current chunk and no additional network requests are made. A `Promise` is still returned but is already resolved. In contrast to a static import, the module isn't executed until the call to `import()` is made. +- `"weak"`: Tries to load the module if the module function has already been loaded in some other way (i. e. another chunk imported it or a script containing the module was loaded). A `Promise` is still returned but, only successfully resolves if the chunks are already on the client. If the module is not available, the `Promise` is rejected. A network request will never be performed. This is useful for universal rendering when required chunks are always manually served in initial requests (embedded within the page), but not in cases where app navigation will trigger an import not initially served. + +T> Note that all options can be combined like so `/* webpackMode: "lazy-once", webpackChunkName: "all-i18n-data" */`. This is wrapped in a JavaScript object and executed using [node VM](https://nodejs.org/dist/latest-v8.x/docs/api/vm.html). You do not need to add curly brackets. + +`webpackInclude`: A regular expression that will be matched against during import resolution. Only modules that match __will be bundled__. + +`webpackExclude`: A regular expression that will be matched against during import resolution. Any module that matches __will not be bundled__. + +T> Note that `webpackInclude` and `webpackExclude` options do not interfere with the prefix. eg: `./locale`. + +W> Fully dynamic statements, such as `import(foo)`, __will fail__ because webpack requires at least some file location information. This is because `foo` could potentially be any path to any file in your system or project. The `import()` must contain at least some information about where the module is located, so bundling can be limited to a specific directory or set of files. + +W> Every module that could potentially be requested on an `import()` call is included. For example, ``import(`./locale/${language}.json`)`` will cause every `.json` file in the `./locale` directory to be bundled into the new chunk. At run time, when the variable `language` has been computed, any file like `english.json` or `german.json` will be available for consumption. Using the `webpackInclude` and `webpackExclude` options allows us to add regex patterns that reduce the files that webpack will bundle for this import. + +W> The use of `System.import` in webpack [did not fit the proposed spec](https://github.com/webpack/webpack/issues/2163), so it was deprecated in webpack [2.1.0-beta.28](https://github.com/webpack/webpack/releases/tag/v2.1.0-beta.28) in favor of `import()`. + + +## CommonJS + +The goal of CommonJS is to specify an ecosystem for JavaScript outside the browser. The following CommonJS methods are supported by webpack: + + +### `require` + +``` javascript +require(dependency: String); +``` + +Synchronously retrieve the exports from another module. The compiler will ensure that the dependency is available in the output bundle. + +``` javascript +var $ = require('jquery'); +var myModule = require('my-module'); +``` + +W> Using it asynchronously may not have the expected effect. + + +### `require.resolve` + +``` javascript +require.resolve(dependency: String); +``` + +Synchronously retrieve a module's ID. The compiler will ensure that the dependency is available in the output bundle. See [`module.id`](/api/module-variables#module-id-commonjs-) for more information. + +W> Module ID is a number in webpack (in contrast to NodeJS where it is a string -- the filename). + + +### `require.cache` + +Multiple requires to the same module result in only one module execution and only one export. Therefore a cache in the runtime exists. Removing values from this cache cause new module execution and a new export. + +W> This is only needed in rare cases for compatibility! + +``` javascript +var d1 = require('dependency'); +require('dependency') === d1; +delete require.cache[require.resolve('dependency')]; +require('dependency') !== d1; +``` + +``` javascript +// in file.js +require.cache[module.id] === module; +require('./file.js') === module.exports; +delete require.cache[module.id]; +require.cache[module.id] === undefined; +require('./file.js') !== module.exports; // in theory; in praxis this causes a stack overflow +require.cache[module.id] !== module; +``` + + +### `require.ensure` + +W> `require.ensure()` is specific to webpack and superseded by `import()`. + + + +```js +require.ensure( + dependencies: String[], + callback: function(require), + errorCallback: function(error), + chunkName: String +) +``` + +Split out the given `dependencies` to a separate bundle that that will be loaded asynchronously. When using CommonJS module syntax, this is the only way to dynamically load dependencies. Meaning, this code can be run within execution, only loading the `dependencies` if certain conditions are met. + +W> This feature relies on [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) internally. If you use `require.ensure` with older browsers, remember to shim `Promise` using a polyfill such as [es6-promise](https://github.com/stefanpenner/es6-promise) or [promise-polyfill](https://github.com/taylorhakes/promise-polyfill). + +``` javascript +var a = require('normal-dep'); + +if ( module.hot ) { + require.ensure(['b'], function(require) { + var c = require('c'); + + // Do something special... + }); +} +``` + +The following parameters are supported in the order specified above: + +- `dependencies`: An array of strings declaring all modules required for the code in the `callback` to execute. +- `callback`: A function that webpack will execute once the dependencies are loaded. An implementation of the `require` function is sent as a parameter to this function. The function body can use this to further `require()` modules it needs for execution. +- `errorCallback`: A function that is executed when webpack fails to load the dependencies. +- `chunkName`: A name given to the chunk created by this particular `require.ensure()`. By passing the same `chunkName` to various `require.ensure()` calls, we can combine their code into a single chunk, resulting in only one bundle that the browser must load. + +W> Although the implementation of `require` is passed as an argument to the `callback` function, using an arbitrary name e.g. `require.ensure([], function(request) { request('someModule'); })` isn't handled by webpack's static parser. Use `require` instead, e.g. `require.ensure([], function(require) { require('someModule'); })`. + + + +## AMD + +Asynchronous Module Definition (AMD) is a JavaScript specification that defines an interface for writing and loading modules. The following AMD methods are supported by webpack: + + +### `define` (with factory) + + + +```js +define([name: String], [dependencies: String[]], factoryMethod: function(...)) +``` + +If `dependencies` are provided, `factoryMethod` will be called with the exports of each dependency (in the same order). If `dependencies` are not provided, `factoryMethod` is called with `require`, `exports` and `module` (for compatibility!). If this function returns a value, this value is exported by the module. The compiler ensures that each dependency is available. + +W> Note that webpack ignores the `name` argument. + +``` javascript +define(['jquery', 'my-module'], function($, myModule) { + // Do something with $ and myModule... + + // Export a function + return function doSomething() { + // ... + }; +}); +``` + +W> This CANNOT be used in an asynchronous function. + + +### `define` (with value) + + + +```js +define(value: !Function) +``` + +This will simply export the provided `value`. The `value` here can be anything except a function. + +``` javascript +define({ + answer: 42 +}); +``` + +W> This CANNOT be used in an async function. + + +### `require` (amd-version) + + + +```js +require(dependencies: String[], [callback: function(...)]) +``` + +Similar to `require.ensure`, this will split the given `dependencies` into a separate bundle that will be loaded asynchronously. The `callback` will be called with the exports of each dependency in the `dependencies` array. + +W> This feature relies on [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) internally. If you use AMD with older browsers (e.g. Internet Explorer 11), remember to shim `Promise` using a polyfill such as [es6-promise](https://github.com/stefanpenner/es6-promise) or [promise-polyfill](https://github.com/taylorhakes/promise-polyfill). + +``` javascript +require(['b'], function(b) { + var c = require('c'); +}); +``` + +W> There is no option to provide a chunk name. + + + +## Labeled Modules + +The internal `LabeledModulesPlugin` enables you to use the following methods for exporting and requiring within your modules: + + +### `export` label + +Export the given `value`. The label can occur before a function declaration or a variable declaration. The function name or variable name is the identifier under which the value is exported. + + + +```js +export: var answer = 42; +export: function method(value) { + // Do something... +}; +``` + +W> Using it in an async function may not have the expected effect. + + +### `require` label + +Make all exports from the dependency available in the current scope. The `require` label can occur before a string. The dependency must export values with the `export` label. CommonJS or AMD modules cannot be consumed. + +__some-dependency.js__ + + + +```js +export: var answer = 42; +export: function method(value) { + // Do something... +}; +``` + + + +```js +require: 'some-dependency'; +console.log(answer); +method(...); +``` + + + +## Webpack + +Aside from the module syntaxes described above, webpack also allows a few custom, webpack-specific methods: + + +### `require.context` + + + +```js +require.context( + directory: String, + includeSubdirs: Boolean /* optional, default true */, + filter: RegExp /* optional, default /^\.\/.*$/, any file */, + mode: String /* optional, 'sync' | 'eager' | 'weak' | 'lazy' | 'lazy-once', default 'sync' */ +) +``` + +Specify a whole group of dependencies using a path to the `directory`, an option to `includeSubdirs`, a `filter` for more fine grained control of the modules included, and a `mode` to define the way how loading will work. Underlying modules can then be easily resolved later on: + +```javascript +var context = require.context('components', true, /\.html$/); +var componentA = context.resolve('componentA'); +``` + +If `mode` is specified as "lazy", the underlying modules will be loaded asynchronously: + +```javascript +var context = require.context('locales', true, /\.json$/, 'lazy'); +context('localeA').then(locale => { + // do something with locale +}); +``` + +The full list of available modes and its behavior is described in [`import()`](#import-) documentation. + +### `require.include` + + + +```js +require.include(dependency: String) +``` + +Include a `dependency` without executing it. This can be used for optimizing the position of a module in the output chunks. + +``` javascript +require.include('a'); +require.ensure(['a', 'b'], function(require) { /* ... */ }); +require.ensure(['a', 'c'], function(require) { /* ... */ }); +``` + +This will result in following output: + +- entry chunk: `file.js` and `a` +- anonymous chunk: `b` +- anonymous chunk: `c` + +Without `require.include('a')` it would be duplicated in both anonymous chunks. + + +### `require.resolveWeak` + +Similar to `require.resolve`, but this won't pull the `module` into the bundle. It's what is considered a "weak" dependency. + +``` javascript +if(__webpack_modules__[require.resolveWeak('module')]) { + // Do something when module is available... +} +if(require.cache[require.resolveWeak('module')]) { + // Do something when module was loaded before... +} + +// You can perform dynamic resolves ("context") +// just as with other require/import methods. +const page = 'Foo'; +__webpack_modules__[require.resolveWeak(`./page/${page}`)]; +``` + +T> `require.resolveWeak` is the foundation of _universal rendering_ (SSR + Code Splitting), as used in packages such as [react-universal-component](https://github.com/faceyspacey/react-universal-component). It allows code to render synchronously on both the server and initial page-loads on the client. It requires that chunks are manually served or somehow available. It's able to require modules without indicating they should be bundled into a chunk. It's used in conjunction with `import()` which takes over when user navigation triggers additional imports. + + +# Node.js API + +webpack provides a Node.js API which can be used directly in Node.js runtime. + +The Node.js API is useful in scenarios in which you need to customize the build or development process since all the reporting and error handling must be done manually and webpack only does the compiling part. For this reason the [`stats`](/configuration/stats) configuration options will not have any effect in the `webpack()` call. + + +## Installation + +To start using webpack Node.js API, first install webpack if you haven’t yet: + +``` bash +npm install --save-dev webpack +``` + +Then require the webpack module in your Node.js script: + +``` js +const webpack = require('webpack'); +``` + +Or if you prefer ES2015: + +``` js +import webpack from 'webpack'; +``` + + +## `webpack()` + +The imported `webpack` function is fed a webpack [Configuration Object](/configuration/) and runs the webpack compiler if a callback function is provided: + +``` js-with-links +const webpack = require("webpack"); + +webpack({ + // [Configuration Object](/configuration/) +}, (err, [stats](#stats-object)) => { + if (err || stats.hasErrors()) { + // [Handle errors here](#error-handling) + } + // Done processing +}); +``` + +T> The `err` object __will not__ include compilation errors and those must be handled separately using `stats.hasErrors()` which will be covered in detail in [Error Handling](#error-handling) section of this guide. The `err` object will only contain webpack-related issues, such as misconfiguration, etc. + +T> You can provide the `webpack` function with an array of configurations. See +the [MultiCompiler](#multicompiler) section below for more information. + + +## Compiler Instance + +If you don’t pass the `webpack` runner function a callback, it will return a +webpack `Compiler` instance. This instance can be used to manually trigger the +webpack runner or have it build and watch for changes, much like the +[CLI](/api/cli/). The `Compiler` instance provides the following methods: + +- `.run(callback)` +- `.watch(watchOptions, handler)` + +Typically, only one master `Compiler` instance is created, although child +compilers can be created in order to delegate specific tasks. The `Compiler` is +ultimately just a function which performs bare minimum functionality to keep a +lifecycle running. It delegates all the loading, bundling, and writing work to +registered plugins. + +The `hooks` property on a `Compiler` instance is used to register a plugin to +any hook event in the `Compiler`'s lifecycle. The +[`WebpackOptionsDefaulter`](https://github.com/webpack/webpack/blob/master/lib/WebpackOptionsDefaulter.js) +and [`WebpackOptionsApply`](https://github.com/webpack/webpack/blob/master/lib/WebpackOptionsApply.js) +utilities are used by webpack to configure its `Compiler` instance with all the +built-in plugins. + +The `run` method is then used to kickstart all compilation work. Upon +completion, the given `callback` function is executed. The final logging of +stats and errors should be done in this `callback` function. + +W> The API only supports a single concurrent compilation at a time. When using +`run`, wait for it to finish before calling `run` or `watch` again. When using +`watch`, call `close` and wait for it to finish before calling `run` or `watch` +again. Concurrent compilations will corrupt the output files. + + +## Run + +Calling the `run` method on the `Compiler` instance is much like the quick run +method mentioned above: + +``` js-with-links +const webpack = require("webpack"); + +const compiler = webpack({ + // [Configuration Object](/configuration/) +}); + +compiler.run((err, [stats](#stats-object)) => { + // ... +}); +``` + + +## Watching + +Calling the `watch` method, triggers the webpack runner, but then watches for +changes (much like CLI: `webpack --watch`), as soon as webpack detects a +change, runs again. Returns an instance of `Watching`. + +``` js +watch(watchOptions, callback); +``` + +``` js-with-links +const webpack = require("webpack"); + +const compiler = webpack({ + // [Configuration Object](/configuration/) +}); + +const watching = compiler.watch({ + // Example [watchOptions](/configuration/watch/#watchoptions) + aggregateTimeout: 300, + poll: undefined +}, (err, [stats](#stats-object)) => { + // Print watch/build result here... + console.log(stats); +}); +``` + +`Watching` options are covered in detail +[here](/configuration/watch/#watchoptions). + +W> Filesystem inaccuracies may trigger multiple builds for a single change. So, +in the example above, the `console.log` statement may fire multiple times for a +single modification. Users should expect this behavior and may check +`stats.hash` to see if the file hash has actually changed. + + +### Close `Watching` + +The `watch` method returns a `Watching` instance that exposes +`.close(callback)` method. Calling this method will end watching: + +``` js +watching.close(() => { + console.log('Watching Ended.'); +}); +``` + +W> It’s not allowed to watch or run again before the existing watcher has been +closed or invalidated. + + +### Invalidate `Watching` + +Using `watching.invalidate`, you can manually invalidate the current compiling +round, without stopping the watch process: + +``` js +watching.invalidate(); +``` + + +## Stats Object + +The `stats` object that is passed as a second argument of the +[`webpack()`](#webpack-) callback, is a good source of information about the +code compilation process. It includes: + +- Errors and Warnings (if any) +- Timings +- Module and Chunk information + +The [webpack CLI](/api/cli) uses this information to display nicely formatted +output in your console. + +T> When using the [`MultiCompiler`](/api/plugins/compiler#multicompiler), a +`MultiStats` instance is returned that fulfills the same interface as `stats`, +i.e. the methods described below. + +This `stats` object exposes the following methods: + + +### `stats.hasErrors()` + +Can be used to check if there were errors while compiling. Returns `true` or +`false`. + + +### `stats.hasWarnings()` + +Can be used to check if there were warnings while compiling. Returns `true` or +`false`. + + +### `stats.toJson(options)` + +Returns compilation information as a JSON object. `options` can be either a +string (a preset) or an object for more granular control: + +``` js-with-links +stats.toJson("minimal"); // [more options: "verbose", etc](/configuration/stats). +``` + +``` js +stats.toJson({ + assets: false, + hash: true +}); +``` + +All available options and presets are described in the stats [documentation](/configuration/stats). + +> Here’s an [example] +(https://github.com/webpack/analyse/blob/master/app/pages/upload/example.json) +of this function’s output. + + +### `stats.toString(options)` + +Returns a formatted string of the compilation information (similar to +[CLI](/api/cli) output). + +Options are the same as [`stats.toJson(options)`](/api/node#stats-tojson-options-) with one addition: + +``` js +stats.toString({ + // Add console colors + colors: true +}); +``` + +Here’s an example of `stats.toString()` usage: + +``` js-with-links +const webpack = require("webpack"); + +webpack({ + // [Configuration Object](/configuration/) +}, (err, stats) => { + if (err) { + console.error(err); + return; + } + + console.log(stats.toString({ + chunks: false, // Makes the build much quieter + colors: true // Shows colors in the console + })); +}); +``` + + +## MultiCompiler + +The `MultiCompiler` module allows webpack to run multiple configurations in +separate compilers. If the `options` parameter in the webpack's NodeJS api is +an array of options, webpack applies separate compilers and calls the +`callback` method at the end of each compiler execution. + +``` js-with-links +var webpack = require('webpack'); + +webpack([ + { entry: './index1.js', output: { filename: 'bundle1.js' } }, + { entry: './index2.js', output: { filename: 'bundle2.js' } } +], (err, [stats](#stats-object)) => { + process.stdout.write(stats.toString() + "\n"); +}) +``` + +W> Multiple configurations will __not be run in parallel__. Each +configuration is only processed after the previous one has finished +processing. To process them in parallel, you can use a third-party solution +like [parallel-webpack](https://www.npmjs.com/package/parallel-webpack). + + +## Error Handling + +For a good error handling, you need to account for these three types of errors: + +- Fatal webpack errors (wrong configuration, etc) +- Compilation errors (missing modules, syntax errors, etc) +- Compilation warnings + +Here’s an example that does all that: + +``` js-with-links +const webpack = require("webpack"); + +webpack({ + // [Configuration Object](/configuration/) +}, (err, stats) => { + if (err) { + console.error(err.stack || err); + if (err.details) { + console.error(err.details); + } + return; + } + + const info = stats.toJson(); + + if (stats.hasErrors()) { + console.error(info.errors); + } + + if (stats.hasWarnings()) { + console.warn(info.warnings); + } + + // Log result... +}); +``` + + +## Custom File Systems + +By default, webpack reads files and writes files to disk using a normal file +system. However, it is possible to change the input or output behavior using a +different kind of file system (memory, webDAV, etc). To accomplish this, one +can change the `inputFileSystem` or `outputFileSystem`. For example, you can +replace the default `outputFileSystem` with +[`memory-fs`](https://github.com/webpack/memory-fs) to write files to memory +instead of to disk: + +``` js +const MemoryFS = require('memory-fs'); +const webpack = require('webpack'); + +const fs = new MemoryFS(); +const compiler = webpack({ /* options*/ }); + +compiler.outputFileSystem = fs; +compiler.run((err, stats) => { + // Read the output later: + const content = fs.readFileSync('...'); +}); +``` + +Note that this is what +[webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware), +used by [webpack-dev-server](https://github.com/webpack/webpack-dev-server) +and many other packages, uses to mysteriously hide your files but continue +serving them up to the browser! + +T> The output file system you provide needs to be compatible with Node’s own +[`fs`](https://nodejs.org/api/fs.html) interface, which requires the `mkdirp` +and `join` helper methods. + + +# Resolvers + +Resolvers are created using the `enhanced-resolve` package. The `Resolver` +class extends the `tapable` class and uses `tapable` to provide a few hooks. +The `enhanced-resolve` package can be used directly to create new resolvers, +however any [`compiler` instance](/api/node/#compiler-instance) has a few resolver instances that can be +tapped into. + +Before reading on, make sure you at least skim through the +[`enhanced-resolve`](https://github.com/webpack/enhanced-resolve) and [`tapable`](/api/plugins/#tapable) documentation. + + +## Types + +There are three types of built-in resolvers available on the `compiler` class: + +- Normal: Resolves a module via an absolute or relative path. +- Context: Resolves a module within a given context. +- Loader: Resolves a webpack [loader](/loaders). + +Depending on need, any one of these built-in resolver used by the `compiler` +can be customized via plugins as such: + +``` js +compiler.resolverFactory.plugin('resolver [type]', resolver => { + resolver.hooks.resolve.tapAsync('MyPlugin', params => { + // ... + }); +}); +``` + +Where `[type]` is one of the three resolvers mention above, specified as: + +- `normal` +- `context` +- `loader` + + +See the `enhanced-resolve` [documentation](https://github.com/webpack/enhanced-resolve) for a full list of hooks and +descriptions. + + +## Configuration Options + +The resolvers mentioned above can also be customized via a configuration file +with the [`resolve`](/configuration/resolve/) or [`resolveLoader`](/configuration/resolve/#resolveloader) options. These options allow +users to change the resolving behavior through a variety of options including +through resolve `plugins`. + +The resolver plugins, e.g. [`DirectoryNamedPlugin`](https://github.com/shaketbaby/directory-named-webpack-plugin), can be included +directly in `resolve.plugins` rather than using standard plugins. Note that the +`resolve` configuration affects the `normal` and `context` resolvers while +`resolveLoader` is used to modify the `loader` resolver. + + +# Stats Data + +When compiling source code with webpack, users can generate a JSON file containing statistics about modules. These statistics can be used to analyze an application's dependency graph as well as to optimize compilation speed. The file is typically generated with the following CLI command: + +``` bash +webpack --profile --json > compilation-stats.json +``` + +The `--json > compilation-stats.json` flag indicates to webpack that it should emit the `compilation-stats.json` containing the dependency graph and various other build information. Typically, the `--profile` flag is also added so that a `profile` section is added to each [`modules` object](#module-objects) containing module-specific compilation stats. + + +## Structure + +The top-level structure of the output JSON file is fairly straightforward but there are a few nested data structures as well. Each nested structure has a dedicated section below to make this document more consumable. Note that you can click links within the top-level structure below to jump to relevant sections and documentation: + +```js-with-links +{ + "version": "1.4.13", // Version of webpack used for the compilation + "hash": "11593e3b3ac85436984a", // Compilation specific hash + "time": 2469, // Compilation time in milliseconds + "filteredModules": 0, // A count of excluded modules when [`exclude`](/configuration/stats/#stats) is passed to the [`toJson`](/api/node/#stats-tojson-options-) method + "outputPath": "/", // path to webpack output directory + "assetsByChunkName": { + // Chunk name to emitted asset(s) mapping + "main": "web.js?h=11593e3b3ac85436984a", + "named-chunk": "named-chunk.web.js", + "other-chunk": [ + "other-chunk.js", + "other-chunk.css" + ] + }, + "assets": [ + // A list of [asset objects](#asset-objects) + ], + "chunks": [ + // A list of [chunk objects](#chunk-objects) + ], + "modules": [ + // A list of [module objects](#module-objects) + ], + "errors": [ + // A list of [error strings](#errors-and-warnings) + ], + "warnings": [ + // A list of [warning strings](#errors-and-warnings) + ] +} +``` + + +### Asset Objects + +Each `assets` object represents an `output` file emitted from the compilation. They all follow a similar structure: + + + +```js +{ + "chunkNames": [], // The chunks this asset contains + "chunks": [ 10, 6 ], // The chunk IDs this asset contains + "emitted": true, // Indicates whether or not the asset made it to the `output` directory + "name": "10.web.js", // The `output` filename + "size": 1058 // The size of the file in bytes +} +``` + + +### Chunk Objects + +Each `chunks` object represents a group of modules known as a [chunk](/glossary#c). Each object follows the following structure: + +```js-with-links +{ + "entry": true, // Indicates whether or not the chunk contains the webpack runtime + "files": [ + // An array of filename strings that contain this chunk + ], + "filteredModules": 0, // See the description in the [top-level structure](#structure) above + "id": 0, // The ID of this chunk + "initial": true, // Indicates whether this chunk is loaded on initial page load or [on demand](/guides/lazy-loading) + "modules": [ + // A list of [module objects](#module-objects) + "web.js?h=11593e3b3ac85436984a" + ], + "names": [ + // An list of chunk names contained within this chunk + ], + "origins": [ + // See the description below... + ], + "parents": [], // Parent chunk IDs + "rendered": true, // Indicates whether or not the chunk went through Code Generation + "size": 188057 // Chunk size in bytes +} +``` + +The `chunks` object will also contain a list of `origins` describing how the given chunk originated. Each `origins` object follows the following schema: + +```js-with-links +{ + "loc": "", // Lines of code that generated this chunk + "module": "(webpack)\\test\\browsertest\\lib\\index.web.js", // Path to the module + "moduleId": 0, // The ID of the module + "moduleIdentifier": "(webpack)\\test\\browsertest\\lib\\index.web.js", // Path to the module + "moduleName": "./lib/index.web.js", // Relative path to the module + "name": "main", // The name of the chunk + "reasons": [ + // A list of the same `reasons` found in [module objects](#module-objects) + ] +} +``` + + +### Module Objects + +What good would these statistics be without some description of the compiled application's actual modules? Each module in the dependency graph is represented by the following structure: + +```js-with-links +{ + "assets": [ + // A list of [asset objects](#asset-objects) + ], + "built": true, // Indicates that the module went through [Loaders](/concepts/loaders), Parsing, and Code Generation + "cacheable": true, // Whether or not this module is cacheable + "chunks": [ + // IDs of chunks that contain this module + ], + "errors": 0, // Number of errors when resolving or processing the module + "failed": false, // Whether or not compilation failed on this module + "id": 0, // The ID of the module (analagous to [`module.id`](/api/module-variables#module-id-commonjs-)) + "identifier": "(webpack)\\test\\browsertest\\lib\\index.web.js", // A unique ID used internally + "name": "./lib/index.web.js", // Path to the actual file + "optional": false, // All requests to this module are with `try... catch` blocks (irrelevant with ESM) + "prefetched": false, // Indicates whether or not the module was [prefetched](/plugins/prefetch-plugin) + "profile": { + // Module specific compilation stats corresponding to the [`--profile` flag](/api/cli#profiling) (in milliseconds) + "building": 73, // Loading and parsing + "dependencies": 242, // Building dependencies + "factory": 11 // Resolving dependencies + }, + "reasons": [ + // See the description below... + ], + "size": 3593, // Estimated size of the module in bytes + "source": "// Should not break it...\r\nif(typeof...", // The stringified raw source + "warnings": 0 // Number of warnings when resolving or processing the module +} +``` + +Every module also contains a list of `reasons` objects describing why that module was included in the dependency graph. Each "reason" is similar to the `origins` seen above in the [chunk objects](#chunk-objects) section: + +```js-with-links +{ + "loc": "33:24-93", // Lines of code that caused the module to be included + "module": "./lib/index.web.js", // Relative path to the module based on [context](/configuration/entry-context/#context) + "moduleId": 0, // The ID of the module + "moduleIdentifier": "(webpack)\\test\\browsertest\\lib\\index.web.js", // Path to the module + "moduleName": "./lib/index.web.js", // A more readable name for the module (used for "pretty-printing") + "type": "require.context", // The [type of request](/api/module-methods) used + "userRequest": "../../cases" // Raw string used for the `import` or `require` request +} +``` + + +### Errors and Warnings + +The `errors` and `warnings` properties each contain a list of strings. Each string contains a message and stack trace: + +``` bash +../cases/parsing/browserify/index.js +Critical dependencies: +2:114-121 This seem to be a pre-built javascript file. Even while this is possible, it's not recommended. Try to require to original source to get better results. + @ ../cases/parsing/browserify/index.js 2:114-121 +``` + +W> Note that the stack traces are removed when `errorDetails: false` is passed to the `toJson` method. The `errorDetails` option is set to `true` by default. + + +# Loader API + +A loader is just a JavaScript module that exports a function. The [loader runner](https://github.com/webpack/loader-runner) calls this function and passes the result of the previous loader or the resource file into it. The `this` context of the function is filled-in by webpack and the [loader runner](https://github.com/webpack/loader-runner) with some useful methods that allow the loader (among other things) to change its invocation style to async, or get query parameters. + +The first loader is passed one argument: the content of the resource file. The compiler expects a result from the last loader. The result should be a `String` or a `Buffer` (which is converted to a string), representing the JavaScript source code of the module. An optional SourceMap result (as JSON object) may also be passed. + +A single result can be returned in __sync mode__. For multiple results the `this.callback()` must be called. In __async mode__ `this.async()` must be called to indicate that the [loader runner](https://github.com/webpack/loader-runner) should wait for an asynchronous result. It returns `this.callback()`. Then the loader must return `undefined` and call that callback. + + +## Examples + +The following sections provide some basic examples of the different types of loaders. Note that the `map` and `meta` parameters are optional, see [`this.callback`](/api/loaders#this-callback) below. + +### Synchronous Loaders + +Either `return` or `this.callback` can be used to return the transformed `content` synchronously: + +__sync-loader.js__ + +``` js +module.exports = function(content, map, meta) { + return someSyncOperation(content); +}; +``` + +The `this.callback` method is more flexible as it allows multiple arguments to be passed as opposed to just the `content`. + +__sync-loader-with-multiple-results.js__ + +``` js +module.exports = function(content, map, meta) { + this.callback(null, someSyncOperation(content), map, meta); + return; // always return undefined when calling callback() +}; +``` + +### Asynchronous Loaders + +For asynchronous loaders, [`this.async`](/api/loaders#this-async) is used to retrieve the `callback` function: + +__async-loader.js__ + +``` js +module.exports = function(content, map, meta) { + var callback = this.async(); + someAsyncOperation(content, function(err, result) { + if (err) return callback(err); + callback(null, result, map, meta); + }); +}; +``` + +__async-loader-with-multiple-results.js__ + +``` js +module.exports = function(content, map, meta) { + var callback = this.async(); + someAsyncOperation(content, function(err, result, sourceMaps, meta) { + if (err) return callback(err); + callback(null, result, sourceMaps, meta); + }); +}; +``` + +T> Loaders were originally designed to work in synchronous loader pipelines, like Node.js (using [enhanced-require](https://github.com/webpack/enhanced-require)), _and_ asynchronous pipelines, like in webpack. However, since expensive synchronous computations are a bad idea in a single-threaded environment like Node.js, we advise to make your loader asynchronously if possible. Synchronous loaders are ok if the amount of computation is trivial. + + +### "Raw" Loader + +By default, the resource file is converted to a UTF-8 string and passed to the loader. By setting the `raw` flag, the loader will receive the raw `Buffer`. Every loader is allowed to deliver its result as `String` or as `Buffer`. The compiler converts them between loaders. + +__raw-loader.js__ + +``` js +module.exports = function(content) { + assert(content instanceof Buffer); + return someSyncOperation(content); + // return value can be a `Buffer` too + // This is also allowed if loader is not "raw" +}; +module.exports.raw = true; +``` + + +### Pitching Loader + +Loaders are __always__ called from right to left. There are some instances where the loader only cares about the __metadata__ behind a request and can ignore the results of the previous loader. The `pitch` method on loaders is called from __left to right__ before the loaders are actually executed (from right to left). For the following [`use`](/configuration/module#rule-use) configuration: + +``` js +module.exports = { + //... + module: { + rules: [ + { + //... + use: [ + 'a-loader', + 'b-loader', + 'c-loader' + ] + } + ] + } +}; +``` + +These steps would occur: + +``` diff +|- a-loader `pitch` + |- b-loader `pitch` + |- c-loader `pitch` + |- requested module is picked up as a dependency + |- c-loader normal execution + |- b-loader normal execution +|- a-loader normal execution +``` + +So why might a loader take advantage of the "pitching" phase? + +First, the `data` passed to the `pitch` method is exposed in the execution phase as well under `this.data` and could be useful for capturing and sharing information from earlier in the cycle. + +``` js +module.exports = function(content) { + return someSyncOperation(content, this.data.value); +}; + +module.exports.pitch = function(remainingRequest, precedingRequest, data) { + data.value = 42; +}; +``` + +Second, if a loader delivers a result in the `pitch` method the process turns around and skips the remaining loaders. In our example above, if the `b-loader`s `pitch` method returned something: + +``` js +module.exports = function(content) { + return someSyncOperation(content); +}; + +module.exports.pitch = function(remainingRequest, precedingRequest, data) { + if (someCondition()) { + return 'module.exports = require(' + JSON.stringify('-!' + remainingRequest) + ');'; + } +}; +``` + +The steps above would be shortened to: + +``` diff +|- a-loader `pitch` + |- b-loader `pitch` returns a module +|- a-loader normal execution +``` + +See the [bundle-loader](https://github.com/webpack-contrib/bundle-loader) for a good example of how this process can be used in a more meaningful way. + + +## The Loader Context + +The loader context represents the properties that are available inside of a loader assigned to the `this` property. + +Given the following example this require call is used: +In `/abc/file.js`: + +``` js +require('./loader1?xyz!loader2!./resource?rrr'); +``` + + +### `this.version` + +__Loader API version.__ Currently `2`. This is useful for providing backwards compatibility. Using the version you can specify custom logic or fallbacks for breaking changes. + + +### `this.context` + +__The directory of the module.__ Can be used as context for resolving other stuff. + +In the example: `/abc` because `resource.js` is in this directory + + +### `this.rootContext` + +Starting with webpack 4, the formerly `this.options.context` is provided as `this.rootContext`. + + +### `this.request` + +The resolved request string. + +In the example: `"/abc/loader1.js?xyz!/abc/node_modules/loader2/index.js!/abc/resource.js?rrr"` + + +### `this.query` + +1. If the loader was configured with an [`options`](/configuration/module/#useentry) object, this will point to that object. +2. If the loader has no `options`, but was invoked with a query string, this will be a string starting with `?`. + +T> Use the [`getOptions` method](https://github.com/webpack/loader-utils#getoptions) from `loader-utils` to extract given loader options. + + +### `this.callback` + +A function that can be called synchronously or asynchronously in order to return multiple results. The expected arguments are: + + + +```js +this.callback( + err: Error | null, + content: string | Buffer, + sourceMap?: SourceMap, + meta?: any +); +``` + +1. The first argument must be an `Error` or `null` +2. The second argument a `string` or a [`Buffer`](https://nodejs.org/api/buffer.html). +3. Optional: The third argument must be a source map that is parsable by [this module](https://github.com/mozilla/source-map). +4. Optional: The fourth option, ignored by webpack, can be anything (e.g. some meta data). + +T> It can be useful to pass an abstract syntax tree (AST), like [`ESTree`](https://github.com/estree/estree), as the fourth argument (`meta`) to speed up the build time if you want to share common ASTs between loaders. + +In case this function is called, you should return undefined to avoid ambiguous loader results. + + +### `this.async` + +Tells the [loader-runner](https://github.com/webpack/loader-runner) that the loader intends to call back asynchronously. Returns `this.callback`. + + +### `this.data` + +A data object shared between the pitch and the normal phase. + + +### `this.cacheable` + +A function that sets the cacheable flag: + +``` typescript +cacheable(flag = true: boolean) +``` + +By default, loader results are flagged as cacheable. Call this method passing `false` to make the loader's result not cacheable. + +A cacheable loader must have a deterministic result, when inputs and dependencies haven't changed. This means the loader shouldn't have other dependencies than specified with `this.addDependency`. + + +### `this.loaders` + +An array of all the loaders. It is writeable in the pitch phase. + + + +```js +loaders = [{request: string, path: string, query: string, module: function}] +``` + +In the example: + +``` js +[ + { + request: '/abc/loader1.js?xyz', + path: '/abc/loader1.js', + query: '?xyz', + module: [Function] + }, + { + request: '/abc/node_modules/loader2/index.js', + path: '/abc/node_modules/loader2/index.js', + query: '', + module: [Function] + } +]; +``` + + +### `this.loaderIndex` + +The index in the loaders array of the current loader. + +In the example: in loader1: `0`, in loader2: `1` + + +### `this.resource` + +The resource part of the request, including query. + +In the example: `"/abc/resource.js?rrr"` + + +### `this.resourcePath` + +The resource file. + +In the example: `"/abc/resource.js"` + + +### `this.resourceQuery` + +The query of the resource. + +In the example: `"?rrr"` + + +### `this.target` + +Target of compilation. Passed from configuration options. + +Example values: `"web"`, `"node"` + + +### `this.webpack` + +This boolean is set to true when this is compiled by webpack. + +T> Loaders were originally designed to also work as Babel transforms. Therefore if you write a loader that works for both, you can use this property to know if there is access to additional loaderContext and webpack features. + + +### `this.sourceMap` + +Should a source map be generated. Since generating source maps can be an expensive task, you should check if source maps are actually requested. + + +### `this.emitWarning` + +``` typescript +emitWarning(warning: Error) +``` + +Emit a warning. + + +### `this.emitError` + +``` typescript +emitError(error: Error) +``` + +Emit an error. + + +### `this.loadModule` + +``` typescript +loadModule(request: string, callback: function(err, source, sourceMap, module)) +``` + +Resolves the given request to a module, applies all configured loaders and calls back with the generated source, the sourceMap and the module instance (usually an instance of [`NormalModule`](https://github.com/webpack/webpack/blob/master/lib/NormalModule.js)). Use this function if you need to know the source code of another module to generate the result. + + +### `this.resolve` + +``` typescript +resolve(context: string, request: string, callback: function(err, result: string)) +``` + +Resolve a request like a require expression. + + +### `this.addDependency` + +``` typescript +addDependency(file: string) +dependency(file: string) // shortcut +``` + +Adds a file as dependency of the loader result in order to make them watchable. For example, [`html-loader`](https://github.com/webpack-contrib/html-loader) uses this technique as it finds `src` and `src-set` attributes. Then, it sets the url's for those attributes as dependencies of the html file that is parsed. + + +### `this.addContextDependency` + +``` typescript +addContextDependency(directory: string) +``` + +Add a directory as dependency of the loader result. + + +### `this.clearDependencies` + +``` typescript +clearDependencies() +``` + +Remove all dependencies of the loader result. Even initial dependencies and these of other loaders. Consider using `pitch`. + + +### `this.emitFile` + +``` typescript +emitFile(name: string, content: Buffer|string, sourceMap: {...}) +``` + +Emit a file. This is webpack-specific. + + +### `this.fs` + +Access to the `compilation`'s `inputFileSystem` property. + + +## Deprecated context properties + +W> The usage of these properties is highly discouraged since we are planning to remove them from the context. They are still listed here for documentation purposes. + + +### `this.exec` + +``` typescript +exec(code: string, filename: string) +``` + +Execute some code fragment like a module. See [this comment](https://github.com/webpack/webpack.js.org/issues/1268#issuecomment-313513988) for a replacement method if needed. + + +### `this.resolveSync` + +``` typescript +resolveSync(context: string, request: string) -> string +``` + +Resolve a request like a require expression. + + +### `this.value` + +Pass values to the next loader. If you know what your result exports if executed as module, set this value here (as a only element array). + + +### `this.inputValue` + +Passed from the last loader. If you would execute the input argument as module, consider reading this variable for a shortcut (for performance). + + +### `this.options` + +W> The `options` property has been deprecated in webpack 3 and removed in webpack 4. + + +### `this.debug` + +A boolean flag. It is set when in debug mode. + + +### `this.minimize` + +Should the result be minimized. + + +### `this._compilation` + +Hacky access to the Compilation object of webpack. + + +### `this._compiler` + +Hacky access to the Compiler object of webpack. + + +### `this._module` + +Hacky access to the Module object being loaded. + + +# Module Variables + +This section covers all __variables__ available in code compiled with webpack. Modules will have access to certain data from the compilation process through `module` and other variables. + + +### `module.loaded` (NodeJS) + +This is `false` if the module is currently executing, and `true` if the sync execution has finished. + + +### `module.hot` (webpack-specific) + +Indicates whether or not [Hot Module Replacement](/concepts/hot-module-replacement) is enabled and provides an interface to the process. See the [HMR API page](/api/hot-module-replacement) for details. + + +### `module.id` (CommonJS) + +The ID of the current module. + +``` javascript +module.id === require.resolve('./file.js'); +``` + + +### `module.exports` (CommonJS) + +Defines the value that will be returned when a consumer makes a `require` call to the module (defaults to a new object). + +``` javascript +module.exports = function doSomething() { + // Do something... +}; +``` + +W> This CANNOT be used in an asynchronous function. + + +### `exports` (CommonJS) + +This variable is equal to default value of `module.exports` (i.e. an object). If `module.exports` gets overwritten, `exports` will no longer be exported. + +``` javascript +exports.someValue = 42; +exports.anObject = { + x: 123 +}; +exports.aFunction = function doSomething() { + // Do something +}; +``` + + +### `global` (NodeJS) + +See [node.js global](https://nodejs.org/api/globals.html#globals_global). + + +### `process` (NodeJS) + +See [node.js process](https://nodejs.org/api/process.html). + + +### `__dirname` (NodeJS) + +Depending on the config option `node.__dirname`: + +- `false`: Not defined +- `mock`: equal "/" +- `true`: [node.js __dirname](https://nodejs.org/api/globals.html#globals_dirname) + +If used inside a expression that is parsed by the Parser, the config option is treated as `true`. + + +### `__filename` (NodeJS) + +Depending on the config option `node.__filename`: + +- `false`: Not defined +- `mock`: equal "/index.js" +- `true`: [node.js __filename](https://nodejs.org/api/globals.html#globals_filename) + +If used inside a expression that is parsed by the Parser, the config option is treated as `true`. + + +### `__resourceQuery` (webpack-specific) + +The resource query of the current module. If the following `require` call were made, then the query string would be available in `file.js`. + +``` javascript +require('file.js?test'); +``` + +__file.js__ + +``` javascript +__resourceQuery === '?test'; +``` + + +### `__webpack_public_path__` (webpack-specific) + +Equals the config options `output.publicPath`. + + +### `__webpack_require__` (webpack-specific) + +The raw require function. This expression isn't parsed by the Parser for dependencies. + + +### `__webpack_chunk_load__` (webpack-specific) + +The internal chunk loading function. Takes two arguments: + +- `chunkId` The id for the chunk to load. +- `callback(require)` A callback function called once the chunk is loaded. + + +### `__webpack_modules__` (webpack-specific) + +Access to the internal object of all modules. + + +### `__webpack_hash__` (webpack-specific) + +This variable is only available with the `HotModuleReplacementPlugin` or the `ExtendedAPIPlugin`. It provides access to the hash of the compilation. + + +### `__non_webpack_require__` (webpack-specific) + +Generates a `require` function that is not parsed by webpack. Can be used to do cool stuff with a global require function if available. + + +### `DEBUG` (webpack-specific) + +Equals the config option `debug`. + + +# Parser + +The `parser` instance, found in the `compiler`, is used to parse each module +being processed by webpack. The `parser` is yet another webpack class that +extends `tapable` and provides a variety of `tapable` hooks that can be used by +plugin authors to customize the parsing process. + +The `parser` is found within [module factories](/api/compiler-hooks/#normalmodulefactory) and therefore takes little +more work to access: + +``` js +compiler.hooks.normalModuleFactory.tap('MyPlugin', factory => { + factory.hooks.parser.for('javascript/auto').tap('MyPlugin', (parser, options) => { + parser.hooks.someHook.tap(/* ... */); + }); +}); +``` + +As with the `compiler`, `tapAsync` and `tapPromise` may also be available +depending on the type of hook. + + +## Hooks + +The following lifecycle hooks are exposed by the `parser` and can be accessed +as such: + + +### evaluateTypeof + +`SyncBailHook` + +Evaluate the type of an identifier. + +Parameters: `expression` + + +### evaluate + +`SyncBailHook` + +Evaluate an expression. + +Parameters: `expression` + + +### evaluateIdentifier + +`SyncBailHook` + +Evaluate an identifier that is a free variable. + +Parameters: `expression` + + +### evaluateDefinedIdentifier + +`SyncBailHook` + +Evaluate an identifier that is a defined variable. + +Parameters: `expression` + + +### evaluateCallExpressionMember + +`SyncBailHook` + +Evaluate a call to a member function of a successfully evaluated expression. + +Parameters: `expression` `param` + + +### statement + +`SyncBailHook` + +General purpose hook that is called when parsing statements in a code fragment. + +Parameters: `statement` + + +### statementIf + +`SyncBailHook` + +... + +Parameters: `statement` + + +### label + +`SyncBailHook` + +... + +Parameters: `statement` + + +### import + +`SyncBailHook` + +... + +Parameters: `statement` `source` + + +### importSpecifier + +`SyncBailHook` + +... + +Parameters: `statement` `source` `exportName` `identifierName` + + +### export + +`SyncBailHook` + +... + +Parameters: `statement` + + +### exportImport + +`SyncBailHook` + +... + +Parameters: `statement` `source` + + +### exportDeclaration + +`SyncBailHook` + +... + +Parameters: `statement` `declaration` + + +### exportExpression + +`SyncBailHook` + +... + +Parameters: `statement` `declaration` + + +### exportSpecifier + +`SyncBailHook` + +... + +Parameters: `statement` `identifierName` `exportName` `index` + + +### exportImportSpecifier + +`SyncBailHook` + +... + +Parameters: `statement` `source` `identifierName` `exportName` `index` + + +### varDeclaration + +`SyncBailHook` + +... + +Parameters: `declaration` + + +### varDeclarationLet + +`SyncBailHook` + +... + +Parameters: `declaration` + + +### varDeclarationConst + +`SyncBailHook` + +... + +Parameters: `declaration` + + +### varDeclarationVar + +`SyncBailHook` + +... + +Parameters: `declaration` + + +### canRename + +`SyncBailHook` + +... + +Parameters: `initExpression` + + +### rename + +`SyncBailHook` + +... + +Parameters: `initExpression` + + +### assigned + +`SyncBailHook` + +... + +Parameters: `expression` + + +### assign + +`SyncBailHook` + +... + +Parameters: `expression` + + +### typeof + +`SyncBailHook` + +... + +Parameters: `expression` + + +### call + +`SyncBailHook` + +... + +Parameters: `expression` + + +### callAnyMember + +`SyncBailHook` + +... + +Parameters: `expression` + + +### new + +`SyncBailHook` + +... + +Parameters: `expression` + + +### expression + +`SyncBailHook` + +... + +Parameters: `expression` + + +### expressionAnyMember + +`SyncBailHook` + +... + +Parameters: `expression` + + +### expressionConditionalOperator + +`SyncBailHook` + +... + +Parameters: `expression` + + +### program + +`SyncBailHook` + +Get access to the abstract syntax tree (AST) of a code fragment + +Parameters: `ast` `comments` diff --git a/src/content/concepts/_concepts_all.md b/src/content/concepts/_concepts_all.md new file mode 100644 index 000000000000..7ea61cfe8aaa --- /dev/null +++ b/src/content/concepts/_concepts_all.md @@ -0,0 +1,1086 @@ + + +# Concepts + +At its core, __webpack__ is a _static module bundler_ for modern JavaScript applications. When webpack processes your application, it internally builds a [dependency graph](/concepts/dependency-graph/) which maps every module your project needs and generates one or more _bundles_. + +T> Learn more about JavaScript modules and webpack modules [here](/concepts/modules). + +Since version 4.0.0, __webpack does not require a configuration file__ to bundle your project, nevertheless it is [incredibly configurable](/configuration) to better fit your needs. + +To get started you only need to understand its __Core Concepts__: + +- [Entry](#entry) +- [Output](#output) +- [Loaders](#loaders) +- [Plugins](#plugins) +- [Mode](#mode) +- [Browser Compatibility](#browser-compatibility) + +This document is intended to give a __high-level__ overview of these concepts, while providing links to detailed concept specific use cases. + +For a better understanding of the ideas behind module bundlers and how they work under the hood consult these resources: + +- [Manually Bundling an Application](https://www.youtube.com/watch?v=UNMkLHzofQI) +- [Live Coding a Simple Module Bundler](https://www.youtube.com/watch?v=Gc9-7PBqOC8) +- [Detailed Explanation of a Simple Module Bundler](https://github.com/ronami/minipack) + + +## Entry + +An __entry point__ indicates which module webpack should use to begin building out its internal [dependency graph](/concepts/dependency-graph/). webpack will figure out which other modules and libraries that entry point depends on (directly and indirectly). + +By default its value is `./src/index.js`, but you can specify a different (or multiple entry points) by configuring the __entry__ property in the [webpack configuration](/configuration). For example: + +__webpack.config.js__ + +``` js +module.exports = { + entry: './path/to/my/entry/file.js' +}; +``` + +T> Learn more in the [entry points](/concepts/entry-points) section. + + +## Output + +The __output__ property tells webpack where to emit the _bundles_ it creates and how to name these files. It defaults to `./dist/main.js` for the main output file and to the `./dist` folder for any other generated file. + +You can configure this part of the process by specifying an `output` field in your configuration: + +__webpack.config.js__ + +```javascript +const path = require('path'); + +module.exports = { + entry: './path/to/my/entry/file.js', + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'my-first-webpack.bundle.js' + } +}; +``` + +In the example above, we use the `output.filename` and the `output.path` properties to tell webpack the name of our bundle and where we want it to be emitted to. In case you're wondering about the path module being imported at the top, it is a core [Node.js module](https://nodejs.org/api/modules.html) that gets used to manipulate file paths. + +T> The `output` property has [many more configurable features](/configuration/output) and if you like to know more about the concepts behind it, you can [read more in the output section](/concepts/output). + + +## Loaders + +Out of the box, webpack only understands JavaScript and JSON files. __Loaders__ allow webpack to process other types of files and convert them into valid [modules](/concepts/modules) that can be consumed by your application and added to the dependency graph. + +W> Note that the ability to `import` any type of module, e.g. `.css` files, is a feature specific to webpack and may not be supported by other bundlers or task runners. We feel this extension of the language is warranted as it allows developers to build a more accurate dependency graph. + +At a high level, __loaders__ have two properties in your webpack configuration: + +1. The `test` property identifies which file or files should be transformed. +2. The `use` property indicates which loader should be used to do the transforming. + +__webpack.config.js__ + +```javascript +const path = require('path'); + +module.exports = { + output: { + filename: 'my-first-webpack.bundle.js' + }, + module: { + rules: [ + { test: /\.txt$/, use: 'raw-loader' } + ] + } +}; +``` + +The configuration above has defined a `rules` property for a single module with two required properties: `test` and `use`. This tells webpack's compiler the following: + +> "Hey webpack compiler, when you come across a path that resolves to a '.txt' file inside of a `require()`/`import` statement, __use__ the `raw-loader` to transform it before you add it to the bundle." + +W> It is important to remember that when defining rules in your webpack config, you are defining them under `module.rules` and not `rules`. For your benefit, webpack will warn you if this is done incorrectly. + +You can check further customization when including loaders in the [loaders section](/concepts/loaders). + + +## Plugins + +While loaders are used to transform certain types of modules, plugins can be leveraged to perform a wider range of tasks like bundle optimization, asset management and injection of environment variables. + +T> Check out the [plugin interface](/api/plugins) and how to use it to extend webpacks capabilities. + +In order to use a plugin, you need to `require()` it and add it to the `plugins` array. Most plugins are customizable through options. Since you can use a plugin multiple times in a config for different purposes, you need to create an instance of it by calling it with the `new` operator. + +__webpack.config.js__ + +```javascript +const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm +const webpack = require('webpack'); //to access built-in plugins + +module.exports = { + module: { + rules: [ + { test: /\.txt$/, use: 'raw-loader' } + ] + }, + plugins: [ + new HtmlWebpackPlugin({template: './src/index.html'}) + ] +}; +``` + +In the example above, the `html-webpack-plugin` generates an HTML file for your application by injecting automatically all your generated bundles. + +T> There are many plugins that webpack provides out of the box! Check out the [list of plugins](/plugins). + +Using plugins in your webpack config is straightforward - however, there are many use cases that are worth further exploration. [Learn more about them here](/concepts/plugins). + + +## Mode + +By setting the `mode` parameter to either `development`, `production` or `none`, you can enable webpack's built-in optimizations that correspond to each environment. The default value is `production`. + +```javascript +module.exports = { + mode: 'production' +}; +``` + +Learn more about the [mode configuration here](/concepts/mode) and what optimizations take place on each value. + + +## Browser Compatibility + +webpack supports all browsers that are [ES5-compliant](https://kangax.github.io/compat-table/es5/) (IE8 and below are not supported). webpack needs `Promise` for `import()` and `require.ensure()`. If you want to support older browsers, you will need to [load a polyfill](/guides/shimming/) before using these expressions. + + +# Entry Points + +As mentioned in [Getting Started](/guides/getting-started/#using-a-configuration), there are multiple ways to define the `entry` property in your webpack configuration. We will show you the ways you __can__ configure the `entry` property, in addition to explaining why it may be useful to you. + + +## Single Entry (Shorthand) Syntax + +Usage: `entry: string|Array` + +__webpack.config.js__ + +```javascript +module.exports = { + entry: './path/to/my/entry/file.js' +}; +``` + +The single entry syntax for the `entry` property is a shorthand for: + +__webpack.config.js__ + +```javascript +module.exports = { + entry: { + main: './path/to/my/entry/file.js' + } +}; +``` + +T> __What happens when you pass an array to `entry`?__ Passing an array of file paths to the `entry` property creates what is known as a __"multi-main entry"__. This is useful when you would like to inject multiple dependent files together and graph their dependencies into one "chunk". + +This is a great choice when you are looking to quickly setup a webpack configuration for an application or tool with one entry point (i.e., a library). However, there is not much flexibility in extending or scaling your configuration with this syntax. + + +## Object Syntax + +Usage: `entry: {[entryChunkName: string]: string|Array}` + +__webpack.config.js__ + +```javascript +module.exports = { + entry: { + app: './src/app.js', + adminApp: './src/adminApp.js' + } +}; +``` + +The object syntax is more verbose. However, this is the most scalable way of defining entry/entries in your application. + +T> __"Scalable webpack configurations"__ are ones that can be reused and combined with other partial configurations. This is a popular technique used to separate concerns by environment, build target and runtime. They are then merged using specialized tools like [webpack-merge](https://github.com/survivejs/webpack-merge). + + +## Scenarios + +Below is a list of entry configurations and their real-world use cases: + +### Separate App and Vendor Entries + +T> In webpack version < 4 it was common to add vendors as separate entrypoint to compile it as separate file (in combination with the `CommonsChunkPlugin`). This is discouraged in webpack 4. Instead the `optimization.splitChunks` option takes care of separating vendors and app modules and creating a separate file. __Do not__ create a entry for vendors or other stuff which is not the starting point of execution. + +### Multi Page Application + +__webpack.config.js__ + +```javascript +module.exports = { + entry: { + pageOne: './src/pageOne/index.js', + pageTwo: './src/pageTwo/index.js', + pageThree: './src/pageThree/index.js' + } +}; +``` + +__What does this do?__ We are telling webpack that we would like 3 separate dependency graphs (like the above example). + +__Why?__ In a multi-page application, the server is going to fetch a new HTML document for you. The page reloads this new document and assets are redownloaded. However, this gives us the unique opportunity to do multiple things: + +- Use `optimization.splitChunks` to create bundles of shared application code between each page. Multi-page applications that reuse a lot of code/modules between entry points can greatly benefit from these techniques, as the amount of entry points increase. + +T> As a rule of thumb: for each HTML document use exactly one entry point. + + +# Output + +Configuring the `output` configuration options tells webpack how to write the compiled files to disk. Note that, while there can be multiple `entry` points, only one `output` configuration is specified. + + +## Usage + +The minimum requirements for the `output` property in your webpack config is to set its value to an object including the following thing: + +- A `filename` to use for the output file(s). + +__webpack.config.js__ + +```javascript +module.exports = { + output: { + filename: 'bundle.js', + } +}; +``` + +This configuration would output a single `bundle.js` file into the `dist` directory. + + +## Multiple Entry Points + +If your configuration creates more than a single "chunk" (as with multiple entry points or when using plugins like CommonsChunkPlugin), you should use [substitutions](/configuration/output#output-filename) to ensure that each file has a unique name. + +```javascript +module.exports = { + entry: { + app: './src/app.js', + search: './src/search.js' + }, + output: { + filename: '[name].js', + path: __dirname + '/dist' + } +}; + +// writes to disk: ./dist/app.js, ./dist/search.js +``` + + +## Advanced + +Here's a more complicated example of using a CDN and hashes for assets: + +__config.js__ + +```javascript +module.exports = { + //... + output: { + path: '/home/proj/cdn/assets/[hash]', + publicPath: 'http://cdn.example.com/assets/[hash]/' + } +}; +``` + +In cases where the eventual `publicPath` of output files isn't known at compile time, it can be left blank and set dynamically at runtime via the `__webpack_public_path__` variable in the entry point file: + +```javascript +__webpack_public_path__ = myRuntimePublicPath; + +// rest of your application entry +``` + + +# Loaders + +Loaders are transformations that are applied on the source code of a module. They allow you to pre-process files as you `import` or “load” them. Thus, loaders are kind of like “tasks” in other build tools and provide a powerful way to handle front-end build steps. Loaders can transform files from a different language (like TypeScript) to JavaScript or inline images as data URLs. Loaders even allow you to do things like `import` CSS files directly from your JavaScript modules! + + +## Example + +For example, you can use loaders to tell webpack to load a CSS file or to convert TypeScript to JavaScript. To do this, you would start by installing the loaders you need: + +``` bash +npm install --save-dev css-loader +npm install --save-dev ts-loader +``` + +And then instruct webpack to use the [`css-loader`](/loaders/css-loader) for every `.css` file and the [`ts-loader`](https://github.com/TypeStrong/ts-loader) for all `.ts` files: + +__webpack.config.js__ + +``` js +module.exports = { + module: { + rules: [ + { test: /\.css$/, use: 'css-loader' }, + { test: /\.ts$/, use: 'ts-loader' } + ] + } +}; +``` + + +## Using Loaders + +There are three ways to use loaders in your application: + +- [Configuration](#configuration) (recommended): Specify them in your __webpack.config.js__ file. +- [Inline](#inline): Specify them explicitly in each `import` statement. +- [CLI](#cli): Specify them within a shell command. + + +### Configuration + +[`module.rules`](/configuration/module/#module-rules) allows you to specify several loaders within your webpack configuration. +This is a concise way to display loaders, and helps to maintain clean code. It also offers you a full overview of each respective loader. + +Loaders are evaluated/executed from right to left. In the example below execution starts with sass-loader, continues with css-loader and finally ends with style-loader. See ["Loader Features"](/concepts/loaders/#loader-features) for more information about loaders order. + +```js-with-links-with-details +module.exports = { + module: { + rules: [ + { + test: /\.css$/, + use: [ + { loader: ['style-loader'](/loaders/style-loader) }, + { + loader: ['css-loader'](/loaders/css-loader), + options: { + modules: true + } + }, + { loader: ['sass-loader'](/loaders/sass-loader) } + ] + } + ] + } +}; +``` + + +### Inline + +It's possible to specify loaders in an `import` statement, or any [equivalent "importing" method](/api/module-methods). Separate loaders from the resource with `!`. Each part is resolved relative to the current directory. + +```js +import Styles from 'style-loader!css-loader?modules!./styles.css'; +``` + +It's possible to override any loaders in the configuration by prefixing the entire rule with `!`. + +Options can be passed with a query parameter, e.g. `?key=value&foo=bar`, or a JSON object, e.g. `?{"key":"value","foo":"bar"}`. + +T> Use `module.rules` whenever possible, as this will reduce boilerplate in your source code and allow you to debug or locate a loader faster if something goes south. + + +### CLI + +You can also use loaders through the CLI: + +```sh +webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader' +``` + +This uses the `jade-loader` for `.jade` files, and the [`style-loader`](/loaders/style-loader) and [`css-loader`](/loaders/css-loader) for `.css` files. + + +## Loader Features + +- Loaders can be chained. Each loader in the chain applies transformations to the processed resource. A chain is executed in reverse order. The first loader passes its result (resource with applied transformations) to the next one, and so forth. Finally, webpack expects JavaScript to be returned by the last loader in the chain. +- Loaders can be synchronous or asynchronous. +- Loaders run in Node.js and can do everything that’s possible there. +- Loaders can be configured with an `options` object (using `query` parameters to set options is still supported but has been deprecated). +- Normal modules can export a loader in addition to the normal `main` via `package.json` with the `loader` field. +- Plugins can give loaders more features. +- Loaders can emit additional arbitrary files. + +Loaders allow more power in the JavaScript ecosystem through preprocessing +functions (loaders). Users now have more flexibility to include fine-grained logic such as compression, packaging, language translations and [more](/loaders). + + +## Resolving Loaders + +Loaders follow the standard [module resolution](/concepts/module-resolution/). In most cases it will be loaded from the [module path](/concepts/module-resolution/#module-paths) (think `npm install`, `node_modules`). + +A loader module is expected to export a function and be written in Node.js compatible JavaScript. They are most commonly managed with npm, but you can also have custom loaders as files within your application. By convention, loaders are usually named `xxx-loader` (e.g. `json-loader`). See ["How to Write a Loader?"](/development/how-to-write-a-loader) for more information. + + +# Mode + +Providing the `mode` configuration option tells webpack to use its built-in optimizations accordingly. + +`string` + +T> Possible values for `mode` are: `none`, `development` or `production`(default). + +## Usage + +Just provide the `mode` option in the config: + +```javascript +module.exports = { + mode: 'production' +}; +``` + + +or pass it as a [CLI](/api/cli/) argument: + +```bash +webpack --mode=production +``` + +The following string values are supported: + +Option | Description +--------------------- | ----------------------- +`development` | Sets `process.env.NODE_ENV` on `DefinePlugin` to value `development`. Enables `NamedChunksPlugin` and `NamedModulesPlugin`. +`production` | Sets `process.env.NODE_ENV` on `DefinePlugin` to value `production`. Enables `FlagDependencyUsagePlugin`, `FlagIncludedChunksPlugin`, `ModuleConcatenationPlugin`, `NoEmitOnErrorsPlugin`, `OccurrenceOrderPlugin`, `SideEffectsFlagPlugin` and `TerserPlugin`. +`none` | Opts out of any default optimization options + +If not set, webpack sets `production` as the default value for `mode`. The supported values for mode are: + +T> Please remember that setting `NODE_ENV` doesn't automatically set `mode`. + + +### Mode: development + + +```diff +// webpack.development.config.js +module.exports = { ++ mode: 'development' +- devtool: 'eval', +- cache: true, +- performance: { +- hints: false +- }, +- output: { +- pathinfo: true +- }, +- optimization: { +- namedModules: true, +- namedChunks: true, +- nodeEnv: 'development', +- flagIncludedChunks: false, +- occurrenceOrder: false, +- sideEffects: false, +- usedExports: false, +- concatenateModules: false, +- splitChunks: { +- hidePathInfo: false, +- minSize: 10000, +- maxAsyncRequests: Infinity, +- maxInitialRequests: Infinity, +- }, +- noEmitOnErrors: false, +- checkWasmTypes: false, +- minimize: false, +- }, +- plugins: [ +- new webpack.NamedModulesPlugin(), +- new webpack.NamedChunksPlugin(), +- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }), +- ] +} +``` + + +### Mode: production + + +```diff +// webpack.production.config.js +module.exports = { ++ mode: 'production', +- performance: { +- hints: 'warning' +- }, +- output: { +- pathinfo: false +- }, +- optimization: { +- namedModules: false, +- namedChunks: false, +- nodeEnv: 'production', +- flagIncludedChunks: true, +- occurrenceOrder: true, +- sideEffects: true, +- usedExports: true, +- concatenateModules: true, +- splitChunks: { +- hidePathInfo: true, +- minSize: 30000, +- maxAsyncRequests: 5, +- maxInitialRequests: 3, +- }, +- noEmitOnErrors: true, +- checkWasmTypes: true, +- minimize: true, +- }, +- plugins: [ +- new TerserPlugin(/* ... */), +- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }), +- new webpack.optimize.ModuleConcatenationPlugin(), +- new webpack.NoEmitOnErrorsPlugin() +- ] +} +``` + + +### Mode: none + + +```diff +// webpack.custom.config.js +module.exports = { ++ mode: 'none', +- performance: { +- hints: false +- }, +- optimization: { +- flagIncludedChunks: false, +- occurrenceOrder: false, +- sideEffects: false, +- usedExports: false, +- concatenateModules: false, +- splitChunks: { +- hidePathInfo: false, +- minSize: 10000, +- maxAsyncRequests: Infinity, +- maxInitialRequests: Infinity, +- }, +- noEmitOnErrors: false, +- checkWasmTypes: false, +- minimize: false, +- }, +- plugins: [] +} +``` + +If you want to change the behavior according to the __mode__ variable inside the _webpack.config.js_, you have to export a function instead of an object: + +```javascript +var config = { + entry: './app.js' + //... +}; + +module.exports = (env, argv) => { + + if (argv.mode === 'development') { + config.devtool = 'source-map'; + } + + if (argv.mode === 'production') { + //... + } + + return config; +}; +``` + + +# Plugins + +__Plugins__ are the [backbone](https://github.com/webpack/tapable) of webpack. webpack itself is built on the __same plugin system__ that you use in your webpack configuration! + +They also serve the purpose of doing __anything else__ that a [loader](/concepts/loaders) cannot do. + + +## Anatomy + +A webpack __plugin__ is a JavaScript object that has an [`apply`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) method. This `apply` method is called by the webpack compiler, giving access to the __entire__ compilation lifecycle. + +__ConsoleLogOnBuildWebpackPlugin.js__ + +```javascript +const pluginName = 'ConsoleLogOnBuildWebpackPlugin'; + +class ConsoleLogOnBuildWebpackPlugin { + apply(compiler) { + compiler.hooks.run.tap(pluginName, compilation => { + console.log('The webpack build process is starting!!!'); + }); + } +} +``` + +The first parameter of the tap method of the compiler hook should be a camelized version of the plugin name. It is advisable to use a constant for this so it can be reused in all hooks. + +## Usage + +Since __plugins__ can take arguments/options, you must pass a `new` instance to the `plugins` property in your webpack configuration. + +Depending on how you are using webpack, there are multiple ways to use plugins. + + +### Configuration + +__webpack.config.js__ + +```javascript +const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm +const webpack = require('webpack'); //to access built-in plugins +const path = require('path'); + +module.exports = { + entry: './path/to/my/entry/file.js', + output: { + filename: 'my-first-webpack.bundle.js', + path: path.resolve(__dirname, 'dist') + }, + module: { + rules: [ + { + test: /\.(js|jsx)$/, + use: 'babel-loader' + } + ] + }, + plugins: [ + new webpack.ProgressPlugin(), + new HtmlWebpackPlugin({template: './src/index.html'}) + ] +}; +``` + + +### Node API + +When using the Node API, you can also pass plugins via the `plugins` property in the configuration. + +__some-node-script.js__ + +```javascript +const webpack = require('webpack'); //to access webpack runtime +const configuration = require('./webpack.config.js'); + +let compiler = webpack(configuration); + +new webpack.ProgressPlugin().apply(compiler); + +compiler.run(function(err, stats) { + // ... +}); +``` + +T> Did you know: The example seen above is extremely similar to the [webpack runtime itself!](https://github.com/webpack/webpack/blob/e7087ffeda7fa37dfe2ca70b5593c6e899629a2c/bin/webpack.js#L290-L292) There are lots of great usage examples hiding in the [webpack source code](https://github.com/webpack/webpack) that you can apply to your own configurations and scripts! + + +# Configuration + +You may have noticed that few webpack configurations look exactly alike. This is because __webpack's configuration file is a JavaScript file that exports a webpack [configuration](/configuration/).__ This configuration is then processed by webpack based upon its defined properties. + +Because it's a standard Node.js CommonJS module, you __can do the following__: + +- import other files via `require(...)` +- use utilities on npm via `require(...)` +- use JavaScript control flow expressions i. e. the `?:` operator +- use constants or variables for often used values +- write and execute functions to generate a part of the configuration + +Use these features when appropriate. + +While they are technically feasible, __the following practices should be avoided__: + +- Access CLI arguments, when using the webpack CLI (instead write your own CLI, or [use `--env`](/configuration/configuration-types/)) +- Export non-deterministic values (calling webpack twice should result in the same output files) +- Write long configurations (instead split the configuration into multiple files) + +T> The most important part to take away from this document is that there are many different ways to format and style your webpack configuration. The key is to stick with something consistent that you and your team can understand and maintain. + +The examples below describe how webpack's configuration can be both expressive and configurable because _it is code_: + +## Simple Configuration + +__webpack.config.js__ + +```javascript +var path = require('path'); + +module.exports = { + mode: 'development', + entry: './foo.js', + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'foo.bundle.js' + } +}; +``` + +_See_: [Configuration section](/configuration/) for the all supported configuration options + +## Multiple Targets + +Along with exporting a single configuration as an object, [function](/configuration/configuration-types/#exporting-a-function) or [Promise](/configuration/configuration-types/#exporting-a-promise), you can export multiple configurations. + +_See_: [Exporting multiple configurations](/configuration/configuration-types/#exporting-multiple-configurations) + +## Using other Configuration Languages + +webpack accepts configuration files written in multiple programming and data languages. + +_See_: [Configuration Languages](/configuration/configuration-languages/) + + +# Modules + +In [modular programming](https://en.wikipedia.org/wiki/Modular_programming), developers break programs up into discrete chunks of functionality called a _module_. + +Each module has a smaller surface area than a full program, making verification, debugging, and testing trivial. +Well-written _modules_ provide solid abstractions and encapsulation boundaries, so that each module has a coherent design and a clear purpose within the overall application. + +Node.js has supported modular programming almost since its inception. +On the web, however, support for _modules_ has been slow to arrive. +Multiple tools exist that support modular JavaScript on the web, with a variety of benefits and limitations. +webpack builds on lessons learned from these systems and applies the concept of _modules_ to any file in your project. + +## What is a webpack Module + +In contrast to [Node.js modules](https://nodejs.org/api/modules.html), webpack _modules_ can express their _dependencies_ in a variety of ways. A few examples are: + +- An [ES2015 `import`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) statement +- A [CommonJS](http://www.commonjs.org/specs/modules/1.0/) `require()` statement +- An [AMD](https://github.com/amdjs/amdjs-api/blob/master/AMD.md) `define` and `require` statement +- An [`@import` statement](https://developer.mozilla.org/en-US/docs/Web/CSS/@import) inside of a css/sass/less file. +- An image url in a stylesheet (`url(...)`) or html (``) file. + +T> webpack 1 requires a specific loader to convert ES2015 `import`, however this is possible out of the box via webpack 2 + +## Supported Module Types + +webpack supports modules written in a variety of languages and preprocessors, via _loaders_. _Loaders_ describe to webpack __how__ to process non-JavaScript _modules_ and include these _dependencies_ into your _bundles_. +The webpack community has built _loaders_ for a wide variety of popular languages and language processors, including: + +- [CoffeeScript](http://coffeescript.org) +- [TypeScript](https://www.typescriptlang.org) +- [ESNext (Babel)](https://babeljs.io) +- [Sass](http://sass-lang.com) +- [Less](http://lesscss.org) +- [Stylus](http://stylus-lang.com) + +And many others! Overall, webpack provides a powerful and rich API for customization that allows one to use webpack for __any stack__, while staying __non-opinionated__ about your development, testing, and production workflows. + +For a full list, see [__the list of loaders__](/loaders) or [__write your own__](/api/loaders). + + +# Why webpack + +To understand why you should use webpack let's do a recap of how we used JavaScript on the web before bundlers were a thing. + +There are two ways to run JavaScript in a browser. First, include a script for each functionality you want to implement, the issue is that the solution is hard to scale as loading too many scripts causes a network bottleneck. The other alternative is to load a big .js file containing all your project code, but this results in an unmaintainable scripts that causes problems in scope, size, readability, fragility and monolith files. + + +## IIFE's - Immediately invoked function expressions + +IIFEs solve scoping issues for large projects. When script files are wrapped by an IIFE, you can safely concatenate or safely combine files without concern of scope collision. + +This lead to tools like Make, Gulp, Grunt, Broccoli or Brunch. These tools are known as task runners and they are used, among other purposes, to concatenate all your project files together in order to solve some of the issues mentioned before. + +However, anytime you want to change one file you have to rebuild the whole thing. Concatenating makes it trivial to reuse scripts across files and makes build optimizations more difficult to implement. How do you even know what code is being used and which is not? + +If you are only using one function from lodash or one date utility from moment.js you are actually adding the entire library and just squishing it together. How do you treeshake the dependencies on your code? Also, lazy loading chunks of code can be hard to achieve at scale and requires a lot of manual work from the developer. + + +## Birth of JavaScript Modules happened thanks to Node.js + +webpack runs on Node.js, a JavaScript runtime that can be used in computers and servers outside a browser environment. + +When Node.js was released a new era started, and it came with new challenges. Now that JavaScript is not running in a browser, how are Node applications supposed to load new chunks of code? There are no html files and script tags that can be added to it. + +CommonJS came out and introduced `require`, which allows you to load and use a module in the current file. This solves scope issues out of the box and which code is used becomes clear since we need to import each module that we are going to need. + + +## npm + Node.js + modules -- mass distribution + +JavaScript is taking over the world as a language, as a platform and as a way to rapidly develop and create fast running applications. + +But there is no browser support for CommonJS. There are no [live bindings](https://medium.com/webpack/the-state-of-javascript-modules-4636d1774358). There are problems with circular references. Sync module resolution loader is slow. While CommonJS was a great solution for Node.js projects, browsers didn't support modules. That's when bundlers and tools like Browserify, RequireJS and SystemJS were created to solve this limitation making it possible to write CommonJS modules that run in a browser. + + +## ESM - ECMAScript Modules + +The good news for web projects is that modules are becoming an official feature in ECMAScript standard, though browser support is still short and early implementations show that bundling is still faster and recommended today. + + +## Wouldn't it be nice… + +...to have something that will not only let us write modules but also support any module format (at least until we get to ESM) and that can handle resources and assets at the same time? + +This is why webpack exists. It's a tool that not only let's you bundle your JavaScript applications, supporting both ESM and CommonJS, but can be extended to support all different kinds of assets like images, fonts and stylesheets. + +webpack cares a lot about performance and it's always adding and improving features like async chunk loading and prefetching to help you deliver the best possible version of your project to the user, always caring about loading times and performance. + + +# Module Resolution + +A resolver is a library which helps in locating a module by its absolute path. +A module can be required as a dependency from another module as: + +```js +import foo from 'path/to/module'; +// or +require('path/to/module'); +``` + +The dependency module can be from the application code or a third party library. The resolver helps +webpack find the module code that needs to be included in the bundle for every such `require`/`import` statement. +webpack uses [enhanced-resolve](https://github.com/webpack/enhanced-resolve) to resolve file paths while bundling modules. + + +## Resolving rules in webpack + +Using `enhanced-resolve`, webpack can resolve three kinds of file paths: + + +### Absolute paths + +```js +import '/home/me/file'; + +import 'C:\\Users\\me\\file'; +``` + +Since we already have the absolute path to the file, no further resolution is required. + + +### Relative paths + +```js +import '../src/file1'; +import './file2'; +``` + +In this case, the directory of the resource file where the `import` or `require` occurs is taken to be the context directory. The relative path specified in the `import/require` is joined to this context path to produce the absolute path to the module. + + +### Module paths + +```js +import 'module'; +import 'module/lib/file'; +``` + +Modules are searched for inside all directories specified in [`resolve.modules`](/configuration/resolve/#resolve-modules). +You can replace the original module path by an alternate path by creating an alias for it using [`resolve.alias`](/configuration/resolve/#resolve-alias) configuration option. + +Once the path is resolved based on the above rule, the resolver checks to see if the path points to a file or a directory. If the path points to a file: + +- If the path has a file extension, then the file is bundled straightaway. +- Otherwise, the file extension is resolved using the [`resolve.extensions`](/configuration/resolve/#resolve-extensions) option, which tells the resolver which extensions (eg - `.js`, `.jsx`) are acceptable for resolution. + +If the path points to a folder, then the following steps are taken to find the right file with the right extension: + +- If the folder contains a `package.json` file, then fields specified in [`resolve.mainFields`](/configuration/resolve/#resolve-mainfields) configuration option are looked up in order, and the first such field in `package.json` determines the file path. +- If there is no `package.json` or if the main fields do not return a valid path, file names specified in the [`resolve.mainFiles`](/configuration/resolve/#resolve-mainfiles) configuration option are looked for in order, to see if a matching filename exists in the imported/required directory . +- The file extension is then resolved in a similar way using the `resolve.extensions` option. + +webpack provides reasonable [defaults](/configuration/resolve) for these options depending on your build target. + + +## Resolving Loaders + +This follows the same rules as those specified for file resolution. But the [`resolveLoader`](/configuration/resolve/#resolveloader) configuration option can be used to have separate resolution rules for loaders. + + +## Caching + +Every filesystem access is cached, so that multiple parallel or serial requests to the same file occur faster. In [watch mode](/configuration/watch/#watch), only modified files are evicted from the cache. If watch mode is off, then the cache gets purged before every compilation. + + +See [Resolve API](/configuration/resolve) to learn more on the configuration options mentioned above. + + +# Dependency Graph + +Any time one file depends on another, webpack treats this as a _dependency_. This allows webpack to take non-code assets, such as images or web fonts, and also provide them as _dependencies_ for your application. + +When webpack processes your application, it starts from a list of modules defined on the command line or in its config file. +Starting from these [_entry points_](/concepts/entry-points/), webpack recursively builds a _dependency graph_ that includes every module your application needs, then bundles all of those modules into a small number of _bundles_ - often, just one - to be loaded by the browser. + +T> Bundling your application is especially powerful for _HTTP/1.1_ clients, as it minimizes the number of times your app has to wait while the browser starts a new request. For _HTTP/2_, you can also use [Code Splitting](/guides/code-splitting/) to achieve best results. + + +# Targets + +Because JavaScript can be written for both server and browser, webpack offers multiple deployment _targets_ that you can set in your webpack [configuration](/configuration). + +W> The webpack `target` property is not to be confused with the `output.libraryTarget` property. For more information see [our guide](/concepts/output/) on the `output` property. + +## Usage + +To set the `target` property, you simply set the target value in your webpack config: + +__webpack.config.js__ + +```javascript +module.exports = { + target: 'node' +}; +``` + +In the example above, using `node` webpack will compile for usage in a Node.js-like environment (uses Node.js `require` to load chunks and not touch any built in modules like `fs` or `path`). + +Each _target_ has a variety of deployment/environment specific additions, support to fit its needs. See what [targets are available](/configuration/target/). + +?>Further expansion for other popular target values + +## Multiple Targets + +Although webpack does __not__ support multiple strings being passed into the `target` property, you can create an isomorphic library by bundling two separate configurations: + +__webpack.config.js__ + +```javascript +const path = require('path'); +const serverConfig = { + target: 'node', + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'lib.node.js' + } + //… +}; + +const clientConfig = { + target: 'web', // <=== can be omitted as default is 'web' + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'lib.js' + } + //… +}; + +module.exports = [ serverConfig, clientConfig ]; +``` + +The example above will create a `lib.js` and `lib.node.js` file in your `dist` folder. + +## Resources + +As seen from the options above there are multiple different deployment _targets_ that you can choose from. Below is a list of examples, and resources that you can refer to. + +- __[compare-webpack-target-bundles](https://github.com/TheLarkInn/compare-webpack-target-bundles)__: A great resource for testing and viewing different webpack _targets_. Also great for bug reporting. +- __[Boilerplate of Electron-React Application](https://github.com/chentsulin/electron-react-boilerplate)__: A good example of a build process for electron's main process and renderer process. + +?> Need to find up to date examples of these webpack targets being used in live code or boilerplates. + + +# The Manifest + +In a typical application or site built with webpack, there are three main types of code: + +1. The source code you, and maybe your team, have written. +2. Any third-party library or "vendor" code your source is dependent on. +3. A webpack runtime and __manifest__ that conducts the interaction of all modules. + +This article will focus on the last of these three parts, the runtime and in particular the manifest. + + +## Runtime + +The runtime, along with the manifest data, is basically all the code webpack needs to connect your modularized application while it's running in the browser. It contains the loading and resolving logic needed to connect your modules as they interact. This includes connecting modules that have already been loaded into the browser as well as logic to lazy-load the ones that haven't. + + +## Manifest + +Once your application hits the browser in the form of `index.html` file, some bundles and a variety of other assets required by your application must be loaded and linked somehow. That `/src` directory you meticulously laid out is now bundled, minified and maybe even split into smaller chunks for lazy-loading by webpack's [`optimization`](/configuration/optimization/). So how does webpack manage the interaction between all of your required modules? This is where the manifest data comes in... + +As the compiler enters, resolves, and maps out your application, it keeps detailed notes on all your modules. This collection of data is called the "Manifest" and it's what the runtime will use to resolve and load modules once they've been bundled and shipped to the browser. No matter which [module syntax](/api/module-methods) you have chosen, those `import` or `require` statements have now become `__webpack_require__` methods that point to module identifiers. Using the data in the manifest, the runtime will be able to find out where to retrieve the modules behind the identifiers. + + +## The Problem + +So now you have a little bit of insight about how webpack works behind the scenes. "But, how does this affect me?", you might ask. The simple answer is that most of the time it doesn't. The runtime will do its thing, utilizing the manifest, and everything will appear to just magically work once your application hits the browser. However, if you decide to improve your projects performance by utilizing browser caching, this process will all of a sudden become an important thing to understand. + +By using content hashes within your bundle file names, you can indicate to the browser when the contents of a file has changed thus invalidating the cache. Once you start doing this though, you'll immediately notice some funny behavior. Certain hashes change even when their contents apparently do not. This is caused by the injection of the runtime and manifest which changes every build. + +See [the manifest section](/guides/output-management/#the-manifest) of our _Output management_ guide to learn how to extract the manifest, and read the guides below to learn more about the intricacies of long term caching. + + +# Hot Module Replacement + +Hot Module Replacement (HMR) exchanges, adds, or removes [modules](/concepts/modules/) while an application is running, without a full reload. This can significantly speed up development in a few ways: + +- Retain application state which is lost during a full reload. +- Save valuable development time by only updating what's changed. +- Modifications made to CSS/JS in the source code results in an instant browser update which is almost comparable to changing styles directly in the browser's dev tools. + + +## How It Works + +Let's go through some different viewpoints to understand exactly how HMR works... + +### In the Application + +The following steps allow modules to be swapped in and out of an application: + +1. The application asks the HMR runtime to check for updates. +2. The runtime asynchronously downloads the updates and notifies the application. +3. The application then asks the runtime to apply the updates. +4. The runtime synchronously applies the updates. + +You can set up HMR so that this process happens automatically, or you can choose to require user interaction for updates to occur. + + +### In the Compiler + +In addition to normal assets, the compiler needs to emit an "update" to allow updating from previous version to the new version. The "update" consists of two parts: + +1. The updated [manifest](/concepts/manifest) (JSON) +2. One or more updated chunks (JavaScript) + +The manifest contains the new compilation hash and a list of all updated chunks. Each of these chunks contains the new code for all updated modules (or a flag indicating that the module was removed). + +The compiler ensures that module IDs and chunk IDs are consistent between these builds. It typically stores these IDs in memory (e.g. with [webpack-dev-server](/configuration/dev-server/)), but it's also possible to store them in a JSON file. + + +### In a Module + +HMR is an opt-in feature that only affects modules containing HMR code. One example would be patching styling through the [`style-loader`](https://github.com/webpack-contrib/style-loader). In order for patching to work, the `style-loader` implements the HMR interface; when it receives an update through HMR, it replaces the old styles with the new ones. + +Similarly, when implementing the HMR interface in a module, you can describe what should happen when the module is updated. However, in most cases, it's not mandatory to write HMR code in every module. If a module has no HMR handlers, the update bubbles up. This means that a single handler can update a complete module tree. If a single module from the tree is updated, the entire set of dependencies is reloaded. + +See the [HMR API page](/api/hot-module-replacement) for details on the `module.hot` interface. + + +### In the Runtime + +Here things get a bit more technical... if you're not interested in the internals, feel free to jump to the [HMR API page](/api/hot-module-replacement) or [HMR guide](/guides/hot-module-replacement). + +For the module system runtime, additional code is emitted to track module `parents` and `children`. On the management side, the runtime supports two methods: `check` and `apply`. + +A `check` makes an HTTP request to the update manifest. If this request fails, there is no update available. If it succeeds, the list of updated chunks is compared to the list of currently loaded chunks. For each loaded chunk, the corresponding update chunk is downloaded. All module updates are stored in the runtime. When all update chunks have been downloaded and are ready to be applied, the runtime switches into the `ready` state. + +The `apply` method flags all updated modules as invalid. For each invalid module, there needs to be an update handler in the module or in its parent(s). Otherwise, the invalid flag bubbles up and invalidates parent(s) as well. Each bubble continues until the app's entry point or a module with an update handler is reached (whichever comes first). If it bubbles up from an entry point, the process fails. + +Afterwards, all invalid modules are disposed (via the dispose handler) and unloaded. The current hash is then updated and all `accept` handlers are called. The runtime switches back to the `idle` state and everything continues as normal. + + +## Get Started + +HMR can be used in development as a LiveReload replacement. [webpack-dev-server](/configuration/dev-server/) supports a `hot` mode in which it tries to update with HMR before trying to reload the whole page. See the [Hot Module Replacement guide](/guides/hot-module-replacement) for details. + +T> As with many other features, webpack's power lies in its customizability. There are _many_ ways of configuring HMR depending on the needs of a particular project. However, for most purposes, `webpack-dev-server` is a good fit and will allow you to get started with HMR quickly. diff --git a/src/content/configuration/_configuration_all.md b/src/content/configuration/_configuration_all.md new file mode 100644 index 000000000000..a1e52dc062a1 --- /dev/null +++ b/src/content/configuration/_configuration_all.md @@ -0,0 +1,5315 @@ + + +# Configuration + +Out of the box, webpack won't require you to use a configuration file. However, it will assume the entry point of your project is `src/index` and will output the result in `dist/main.js` minified and optimized for production. + +Usually your projects will need to extend this functionality, for this you can create a `webpack.config.js` file in the root folder and webpack will automatically use it. + +All the available configuration options are specified below. + +T> New to webpack? Check out our guide to some of webpack's [core concepts](/concepts/) to get started! + +## Options + +Click on the name of each option in the configuration code below to jump to the detailed documentation. Also note that the items with arrows can be expanded to show more examples and, in some cases, more advanced configuration. + +W> Notice that throughout the configuration we use Node's built-in [path module](https://nodejs.org/api/path.html) and prefix it with the [__dirname](https://nodejs.org/docs/latest/api/globals.html#globals_dirname) global. This prevents file path issues between operating systems and allows relative paths to work as expected. See [this section](https://nodejs.org/api/path.html#path_windows_vs_posix) for more info on POSIX vs. Windows paths. + +__webpack.config.js__ + +```js-with-links-with-details +const path = require('path'); + +module.exports = { +
[mode](/concepts/mode): "production", // "production" | "development" | "none" + [mode](/concepts/mode): "production", // enable many optimizations for production builds + [mode](/concepts/mode): "development", // enabled useful tools for development + [mode](/concepts/mode): "none", // no defaults +
+ // Chosen mode tells webpack to use its built-in optimizations accordingly. +
[entry](/configuration/entry-context#entry): "./app/entry", // string | object | array + [entry](/configuration/entry-context#entry): ["./app/entry1", "./app/entry2"], + [entry](/configuration/entry-context#entry): { + a: "./app/entry-a", + b: ["./app/entry-b1", "./app/entry-b2"] + }, +
+ // defaults to './src' + // Here the application starts executing + // and webpack starts bundling + [output](/configuration/output): { + // options related to how webpack emits results + [path](/configuration/output#output-path): path.resolve(__dirname, "dist"), // string + // the target directory for all output files + // must be an absolute path (use the Node.js path module) +
[filename](/configuration/output#output-filename): "bundle.js", // string + [filename](/configuration/output#output-filename): "[name].js", // for multiple entry points + [filename](/configuration/output#output-filename): "[chunkhash].js", // for [long term caching](/guides/caching) +
+ // the filename template for entry chunks +
[publicPath](/configuration/output#output-publicpath): "/assets/", // string + [publicPath](/configuration/output#output-publicpath): "", + [publicPath](/configuration/output#output-publicpath): "https://cdn.example.com/", +
+ // the url to the output directory resolved relative to the HTML page + [library](/configuration/output#output-library): "MyLibrary", // string, + // the name of the exported library +
[libraryTarget](/configuration/output#output-librarytarget): "umd", // universal module definition + [libraryTarget](/configuration/output#output-librarytarget): "umd2", // universal module definition + [libraryTarget](/configuration/output#output-librarytarget): "commonjs2", // exported with module.exports + [libraryTarget](/configuration/output#output-librarytarget): "commonjs", // exported as properties to exports + [libraryTarget](/configuration/output#output-librarytarget): "amd", // defined with AMD defined method + [libraryTarget](/configuration/output#output-librarytarget): "this", // property set on this + [libraryTarget](/configuration/output#output-librarytarget): "var", // variable defined in root scope + [libraryTarget](/configuration/output#output-librarytarget): "assign", // blind assignment + [libraryTarget](/configuration/output#output-librarytarget): "window", // property set to window object + [libraryTarget](/configuration/output#output-librarytarget): "global", // property set to global object + [libraryTarget](/configuration/output#output-librarytarget): "jsonp", // jsonp wrapper +
+ // the type of the exported library +
/* Advanced output configuration (click to show) */ + [pathinfo](/configuration/output#output-pathinfo): true, // boolean + // include useful path info about modules, exports, requests, etc. into the generated cod + [chunkFilename](/configuration/output#output-chunkfilename): "[id].js", + [chunkFilename](/configuration/output#output-chunkfilename): "[chunkhash].js", // for [long term caching](/guides/caching) + // the filename template for additional chunks + [jsonpFunction](/configuration/output#output-jsonpfunction): "myWebpackJsonp", // string + // name of the JSONP function used to load chunks + [sourceMapFilename](/configuration/output#output-sourcemapfilename): "[file].map", // string + [sourceMapFilename](/configuration/output#output-sourcemapfilename): "sourcemaps/[file].map", // string + // the filename template of the source map location + [devtoolModuleFilenameTemplate](/configuration/output#output-devtoolmodulefilenametemplate): "webpack:///[resource-path]", // string + // the name template for modules in a devtool + [devtoolFallbackModuleFilenameTemplate](/configuration/output#output-devtoolfallbackmodulefilenametemplate): "webpack:///[resource-path]?[hash]", // string + // the name template for modules in a devtool (used for conflicts) + [umdNamedDefine](/configuration/output#output-umdnameddefine): true, // boolean + // use a named AMD module in UMD library + [crossOriginLoading](/configuration/output#output-crossoriginloading): "use-credentials", // enum + [crossOriginLoading](/configuration/output#output-crossoriginloading): "anonymous", + [crossOriginLoading](/configuration/output#output-crossoriginloading): false, + // specifies how cross origin request are issued by the runtime +
/* Expert output configuration (on own risk) */ + [devtoolLineToLine](/configuration/output#output-devtoollinetoline): { + test: /\.jsx$/ + }, + // use a simple 1:1 mapped SourceMaps for these modules (faster) + [hotUpdateMainFilename](/configuration/output#output-hotupdatemainfilename): "[hash].hot-update.json", // string + // filename template for HMR manifest + [hotUpdateChunkFilename](/configuration/output#output-hotupdatechunkfilename): "[id].[hash].hot-update.js", // string + // filename template for HMR chunks + [sourcePrefix](/configuration/output#output-sourceprefix): "\t", // string + // prefix module sources in bundle for better readablitity +
+
+ }, + [module](/configuration/module): { + // configuration regarding modules + [rules](/configuration/module#module-rules): [ + // rules for modules (configure loaders, parser options, etc.) + { + [test](/configuration/module#rule-test): /\.jsx?$/, + [include](/configuration/module#rule-include): [ + path.resolve(__dirname, "app") + ], + [exclude](/configuration/module#rule-exclude): [ + path.resolve(__dirname, "app/demo-files") + ], + // these are matching conditions, each accepting a regular expression or string + // test and include have the same behavior, both must be matched + // exclude must not be matched (takes preference over test and include) + // Best practices: + // - Use RegExp only in test and for filename matching + // - Use arrays of absolute paths in include and exclude + // - Try to avoid exclude and prefer include + [issuer](/configuration/module#rule-issuer): { test, include, exclude }, + // conditions for the issuer (the origin of the import) + [enforce](/configuration/module#rule-enforce): "pre", + [enforce](/configuration/module#rule-enforce): "post", + // flags to apply these rules, even if they are overridden (advanced option) + [loader](/configuration/module#rule-loader): "babel-loader", + // the loader which should be applied, it'll be resolved relative to the context + // -loader suffix is no longer optional in webpack2 for clarity reasons + // see [webpack 1 upgrade guide](/migrate/3/#automatic-loader-module-name-extension-removed) + [options](/configuration/module#rule-options-rule-query): { + presets: ["es2015"] + }, + // options for the loader + }, + { + [test](/configuration/module#rule-test): /\.html$/, + [use](/configuration/module#rule-use): [ + // apply multiple loaders and options + "htmllint-loader", + { + loader: "html-loader", + options: { + /* ... */ + } + } + ] + }, + { [oneOf](/configuration/module#rule-oneof): [ /* rules */ ] }, + // only use one of these nested rules + { [rules](/configuration/module#rule-rules): [ /* rules */ ] }, + // use all of these nested rules (combine with conditions to be useful) + { [resource](/configuration/module#rule-resource): { [and](/configuration/module#condition): [ /* conditions */ ] } }, + // matches only if all conditions are matched + { [resource](/configuration/module#rule-resource): { [or](/configuration/module#condition): [ /* conditions */ ] } }, + { [resource](/configuration/module#rule-resource): [ /* conditions */ ] }, + // matches if any condition is matched (default for arrays) + { [resource](/configuration/module#rule-resource): { [not](/configuration/module#condition): /* condition */ } } + // matches if the condition is not matched + ], +
/* Advanced module configuration (click to show) */ + [noParse](/configuration/module#module-noparse): [ + /special-library\.js$/ + ], + // do not parse this module + unknownContextRequest: ".", + unknownContextRecursive: true, + unknownContextRegExp: /^\.\/.*$/, + unknownContextCritical: true, + exprContextRequest: ".", + exprContextRegExp: /^\.\/.*$/, + exprContextRecursive: true, + exprContextCritical: true, + wrappedContextRegExp: /.*/, + wrappedContextRecursive: true, + wrappedContextCritical: false, + // specifies default behavior for dynamic requests +
+ }, + [resolve](/configuration/resolve): { + // options for resolving module requests + // (does not apply to resolving to loaders) + [modules](/configuration/resolve#resolve-modules): [ + "node_modules", + path.resolve(__dirname, "app") + ], + // directories where to look for modules + [extensions](/configuration/resolve#resolve-extensions): [".js", ".json", ".jsx", ".css"], + // extensions that are used + [alias](/configuration/resolve#resolve-alias): { + // a list of module name aliases + "module": "new-module", + // alias "module" -> "new-module" and "module/path/file" -> "new-module/path/file" + "only-module$": "new-module", + // alias "only-module" -> "new-module", but not "only-module/path/file" -> "new-module/path/file" + "module": path.resolve(__dirname, "app/third/module.js"), + // alias "module" -> "./app/third/module.js" and "module/file" results in error + // modules aliases are imported relative to the current context + }, +
/* alternative alias syntax (click to show) */ + [alias](/configuration/resolve#resolve-alias): [ + { + name: "module", + // the old request + alias: "new-module", + // the new request + onlyModule: true + // if true only "module" is aliased + // if false "module/inner/path" is also aliased + } + ], +
+
/* Advanced resolve configuration (click to show) */ + [symlinks](/configuration/resolve#resolve-symlinks): true, + // follow symlinks to new location + [descriptionFiles](/configuration/resolve#resolve-descriptionfiles): ["package.json"], + // files that are read for package description + [mainFields](/configuration/resolve#resolve-mainfields): ["main"], + // properties that are read from description file + // when a folder is requested + [aliasFields](/configuration/resolve#resolve-aliasfields): ["browser"], + // properties that are read from description file + // to alias requests in this package + [enforceExtension](/configuration/resolve#resolve-enforceextension): false, + // if true request must not include an extensions + // if false request may already include an extension + [moduleExtensions](/configuration/resolve#resolveloader-moduleextensions): ["-module"], + [enforceModuleExtension](/configuration/resolve#resolve-enforcemoduleextension): false, + // like extensions/enforceExtension but for module names instead of files + [unsafeCache](/configuration/resolve#resolve-unsafecache): true, + [unsafeCache](/configuration/resolve#resolve-unsafecache): {}, + // enables caching for resolved requests + // this is unsafe as folder structure may change + // but performance improvement is really big + [cachePredicate](/configuration/resolve#resolve-cachepredicate): (path, request) => true, + // predicate function which selects requests for caching + [plugins](/configuration/resolve#resolve-plugins): [ + // ... + ] + // additional plugins applied to the resolver +
+ }, + [performance](/configuration/performance): { +
[hints](/configuration/performance#performance-hints): "warning", // enum + [hints](/configuration/performance#performance-hints): "error", // emit errors for perf hints + [hints](/configuration/performance#performance-hints): false, // turn off perf hints +
+ [maxAssetSize](/configuration/performance#performance-maxassetsize): 200000, // int (in bytes), + [maxEntrypointSize](/configuration/performance#performance-maxentrypointsize): 400000, // int (in bytes) + [assetFilter](/configuration/performance#performance-assetfilter): function(assetFilename) { + // Function predicate that provides asset filenames + return assetFilename.endsWith('.css') || assetFilename.endsWith('.js'); + } + }, +
[devtool](/configuration/devtool): "source-map", // enum + [devtool](/configuration/devtool): "inline-source-map", // inlines SourceMap into original file + [devtool](/configuration/devtool): "eval-source-map", // inlines SourceMap per module + [devtool](/configuration/devtool): "hidden-source-map", // SourceMap without reference in original file + [devtool](/configuration/devtool): "cheap-source-map", // cheap-variant of SourceMap without module mappings + [devtool](/configuration/devtool): "cheap-module-source-map", // cheap-variant of SourceMap with module mappings + [devtool](/configuration/devtool): "eval", // no SourceMap, but named modules. Fastest at the expense of detail. +
+ // enhance debugging by adding meta info for the browser devtools + // source-map most detailed at the expense of build speed. + [context](/configuration/entry-context#context): __dirname, // string (absolute path!) + // the home directory for webpack + // the [entry](/configuration/entry-context) and [module.rules.loader](/configuration/module#rule-loader) option + // is resolved relative to this directory +
[target](/configuration/target): "web", // enum + [target](/configuration/target): "webworker", // WebWorker + [target](/configuration/target): "node", // Node.js via require + [target](/configuration/target): "async-node", // Node.js via fs and vm + [target](/configuration/target): "node-webkit", // nw.js + [target](/configuration/target): "electron-main", // electron, main process + [target](/configuration/target): "electron-renderer", // electron, renderer process + [target](/configuration/target): (compiler) => { /* ... */ }, // custom +
+ // the environment in which the bundle should run + // changes chunk loading behavior and available modules +
[externals](/configuration/externals): ["react", /^@angular\//], + [externals](/configuration/externals): "react", // string (exact match) + [externals](/configuration/externals): /^[a-z\-]+($|\/)/, // Regex + [externals](/configuration/externals): { // object + angular: "this angular", // this["angular"] + react: { // UMD + commonjs: "react", + commonjs2: "react", + amd: "react", + root: "React" + } + }, + [externals](/configuration/externals): (request) => { /* ... */ return "commonjs " + request } +
+ // Don't follow/bundle these modules, but request them at runtime from the environment + [serve](https://github.com/webpack-contrib/webpack-serve#options): { //object + port: 1337, + content: './dist', + // ... + }, + // lets you provide options for webpack-serve +
[stats](/configuration/stats): "errors-only", + [stats](/configuration/stats): { //object + assets: true, + colors: true, + errors: true, + errorDetails: true, + hash: true, + // ... + }, +
+ // lets you precisely control what bundle information gets displayed + [devServer](/configuration/dev-server): { + proxy: { // proxy URLs to backend development server + '/api': 'http://localhost:3000' + }, + contentBase: path.join(__dirname, 'public'), // boolean | string | array, static file location + compress: true, // enable gzip compression + historyApiFallback: true, // true for index.html upon 404, object for multiple paths + hot: true, // hot module replacement. Depends on HotModuleReplacementPlugin + https: false, // true for self-signed, object for cert authority + noInfo: true, // only errors & warns on hot reload + // ... + }, + [plugins](plugins): [ + // ... + ], + // list of additional plugins +
/* Advanced configuration (click to show) */ + [resolveLoader](/configuration/resolve#resolveloader): { /* same as resolve */ } + // separate resolve options for loaders + [parallelism](other-options#parallelism): 1, // number + // limit the number of parallel processed modules + [profile](other-options#profile): true, // boolean + // capture timing information + [bail](other-options#bail): true, //boolean + // fail out on the first error instead of tolerating it. + [cache](other-options#cache): false, // boolean + // disable/enable caching + [watch](watch#watch): true, // boolean + // enables watching + [watchOptions](watch#watchoptions): { + [aggregateTimeout](watch#watchoptions-aggregatetimeout): 1000, // in ms + // aggregates multiple changes to a single rebuild + [poll](watch#watchoptions-poll): true, + [poll](watch#watchoptions-poll): 500, // interval in ms + // enables polling mode for watching + // must be used on filesystems that doesn't notify on change + // i. e. nfs shares + }, + [node](node): { + // Polyfills and mocks to run Node.js- + // environment code in non-Node environments. + [console](node#node-console): false, // boolean | "mock" + [global](node#node-global): true, // boolean | "mock" + [process](node#node-process): true, // boolean + [__filename](node#node-__filename): "mock", // boolean | "mock" + [__dirname](node#node-__dirname): "mock", // boolean | "mock" + [Buffer](node#node-buffer): true, // boolean | "mock" + [setImmediate](node#node-setimmediate): true // boolean | "mock" | "empty" + }, + [recordsPath](other-options#recordspath): path.resolve(__dirname, "build/records.json"), + [recordsInputPath](other-options#recordsinputpath): path.resolve(__dirname, "build/records.json"), + [recordsOutputPath](other-options#recordsoutputpath): path.resolve(__dirname, "build/records.json"), + // TODO +
+} +``` + +## Use custom configuration file + +If for some reason you want to use custom configuration file depending on certain situations you can change this via command line by using the `--config` flag. + +__package.json__ + +```json +"scripts": { + "build": "webpack --config prod.config.js" +} +``` + +## Configuration file generators + +Want to rapidly generate webpack configuration file for your project requirements with few clicks away? + +[Generate Custom Webpack Configuration](https://generatewebpackconfig.netlify.com/) is an interactive portal you can play around by selecting custom webpack configuration options tailored for your frontend project. It automatically generates a minimal webpack configuration based on your selection of loaders/plugins, etc. + +[Visual tool for creating webpack configs](https://webpack.jakoblind.no/) is an online configuration tool for creating webpack configuration file where you can select any combination of features you need. It also generates a full example project based on your webpack configs. + + +# Configuration Languages + +webpack accepts configuration files written in multiple programming and data languages. The list of supported file extensions can be found at the [node-interpret](https://github.com/js-cli/js-interpret) package. Using [node-interpret](https://github.com/js-cli/js-interpret), webpack can handle many different types of configuration files. + + +## TypeScript + +To write the webpack configuration in [TypeScript](http://www.typescriptlang.org/), you would first install the necessary dependencies, i.e., TypeScript and the relevant type definitions from the [DefinitelyTyped](https://definitelytyped.org/) project: + +``` bash +npm install --save-dev typescript ts-node @types/node @types/webpack +# and, if using webpack-dev-server +npm install --save-dev @types/webpack-dev-server +``` + +and then proceed to write your configuration: + +__webpack.config.ts__ + +```typescript +import path from 'path'; +import webpack from 'webpack'; + +const config: webpack.Configuration = { + mode: 'production', + entry: './foo.js', + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'foo.bundle.js' + } +}; + +export default config; +``` + +Above sample assumes version >= 2.7 or newer of TypeScript is used with the new `esModuleInterop` and `allowSyntheticDefaultImports` compiler options in your `tsconfig.json` file. + +Note that you'll also need to check your `tsconfig.json` file. If the module in `compilerOptions` in `tsconfig.json` is `commonjs`, the setting is complete, else webpack will fail with an error. This occurs because `ts-node` does not support any module syntax other than `commonjs`. + +There are two solutions to this issue: + +- Modify `tsconfig.json`. +- Install `tsconfig-paths`. + +The __first option__ is to open your `tsconfig.json` file and look for `compilerOptions`. Set `target` to `"ES5"` and `module` to `"CommonJS"` (or completely remove the `module` option). + +The __second option__ is to install the `tsconfig-paths` package: + +``` bash +npm install --save-dev tsconfig-paths +``` + +And create a separate TypeScript configuration specifically for your webpack configs: + +__tsconfig-for-webpack-config.json__ + +``` json +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "esModuleInterop": true + } +} +``` + +T> `ts-node` can resolve a `tsconfig.json` file using the environment variable provided by `tsconfig-path`. + +Then set the environment variable `process.env.TS_NODE_PROJECT` provided by `tsconfig-path` like so: + +__package.json__ + +```json +{ + "scripts": { + "build": "TS_NODE_PROJECT=\"tsconfig-for-webpack-config.json\" webpack" + } +} +``` + + +## CoffeeScript + +Similarly, to use [CoffeeScript](http://coffeescript.org/), you would first install the necessary dependencies: + +``` bash +npm install --save-dev coffee-script +``` + +and then proceed to write your configuration: + +__webpack.config.coffee__ + + + +```js +HtmlWebpackPlugin = require('html-webpack-plugin') +webpack = require('webpack') +path = require('path') + +config = + mode: 'production' + entry: './path/to/my/entry/file.js' + output: + path: path.resolve(__dirname, 'dist') + filename: 'my-first-webpack.bundle.js' + module: rules: [ { + test: /\.(js|jsx)$/ + use: 'babel-loader' + } ] + plugins: [ + new HtmlWebpackPlugin(template: './src/index.html') + ] + +module.exports = config +``` + + +## Babel and JSX + +In the example below JSX (React JavaScript Markup) and Babel are used to create a JSON Configuration that webpack can understand. + +> Courtesy of [Jason Miller](https://twitter.com/_developit/status/769583291666169862) + +First install the necessary dependencies: + +``` bash +npm install --save-dev babel-register jsxobj babel-preset-es2015 +``` + +__.babelrc__ + +``` json +{ + "presets": [ "es2015" ] +} +``` + +__webpack.config.babel.js__ + +``` js +import jsxobj from 'jsxobj'; + +// example of an imported plugin +const CustomPlugin = config => ({ + ...config, + name: 'custom-plugin' +}); + +export default ( + + + + + + + + + +); +``` + +W> If you are using Babel elsewhere and have `modules` set to `false`, you will have to either maintain two separate `.babelrc` files or use `const jsxobj = require('jsxobj');` and `module.exports` instead of the new `import` and `export` syntax. This is because while Node does support many new ES6 features, they don't yet support ES6 module syntax. + + +# Configuration Types + +Besides exporting a single config object, there are a few more ways that cover other needs as well. + + +## Exporting a Function + +Eventually you will find the need to disambiguate in your `webpack.config.js` between [development](/guides/development) and [production builds](/guides/production). You have (at least) two options: + +One option is to export a function from your webpack config instead of exporting an object. The function will be invoked with two arguments: + +- An environment as the first parameter. See the [environment options CLI documentation](/api/cli#environment-options) for syntax examples. +- An options map (`argv`) as the second parameter. This describes the options passed to webpack, with keys such as [`output-filename`](/api/cli/#output-options) and [`optimize-minimize`](/api/cli/#optimize-options). + +```diff +-module.exports = { ++module.exports = function(env, argv) { ++ return { ++ mode: env.production ? 'production' : 'development', ++ devtool: env.production ? 'source-maps' : 'eval', + plugins: [ + new TerserPlugin({ + terserOptions: { ++ compress: argv['optimize-minimize'] // only if -p or --optimize-minimize were passed + } + }) + ] ++ }; +}; +``` + + +## Exporting a Promise + +webpack will run the function exported by the configuration file and wait for a Promise to be returned. Handy when you need to asynchronously load configuration variables. + +```js +module.exports = () => { + return new Promise((resolve, reject) => { + setTimeout(() => { + resolve({ + entry: './app.js', + /* ... */ + }); + }, 5000); + }); +}; +``` + + +## Exporting multiple configurations + +Instead of exporting a single configuration object/function, you may export multiple configurations (multiple functions are supported since webpack 3.1.0). When running webpack, all configurations are built. For instance, this is useful for [bundling a library](/guides/author-libraries) for multiple [targets](/configuration/output#output-librarytarget) such as AMD and CommonJS: + +```js +module.exports = [{ + output: { + filename: './dist-amd.js', + libraryTarget: 'amd' + }, + name: 'amd', + entry: './app.js', + mode: 'production', +}, { + output: { + filename: './dist-commonjs.js', + libraryTarget: 'commonjs' + }, + name: 'commonjs', + entry: './app.js', + mode: 'production', +}]; +``` + +T> If you pass a name to [`--config-name`](/api/cli/#config-options) flag, webpack will only build that specific configuration. + + +# Entry and Context + +The entry object is where webpack looks to start building the bundle. The context is an absolute string to the directory that contains the entry files. + + +## `context` + +`string` + +The base directory, an __absolute path__, for resolving entry points and loaders from configuration. + +``` js +module.exports = { + //... + context: path.resolve(__dirname, 'app') +}; +``` + +By default the current directory is used, but it's recommended to pass a value in your configuration. This makes your configuration independent from CWD (current working directory). + +--- + + +## `entry` + +`string | [string] | object { : string | [string] } | (function: () => string | [string] | object { : string | [string] })` + +The point or points to enter the application. At this point the application starts executing. If an array is passed all items will be executed. + +A dynamically loaded module is __not__ an entry point. + +Simple rule: one entry point per HTML page. SPA: one entry point, MPA: multiple entry points. + +```js +module.exports = { + //... + entry: { + home: './home.js', + about: './about.js', + contact: './contact.js' + } +}; +``` + + +### Naming + +If a string or array of strings is passed, the chunk is named `main`. If an object is passed, each key is the name of a chunk, and the value describes the entry point for the chunk. + + +### Dynamic entry + +If a function is passed then it will be invoked on every [make](/api/compiler-hooks/#make) event. + +> Note that the make event triggers when webpack starts and for every invalidation when [watching for file changes](/configuration/watch/). + +```js +module.exports = { + //... + entry: () => './demo' +}; +``` + +or + +```js +module.exports = { + //... + entry: () => new Promise((resolve) => resolve(['./demo', './demo2'])) +}; +``` + +For example: you can use dynamic entries to get the actual entries from an external source (remote server, file system content or database): + +__webpack.config.js__ + +``` js +module.exports = { + entry() { + return fetchPathsFromSomeExternalSource(); // returns a promise that will be resolved with something like ['src/main-layout.js', 'src/admin-layout.js'] + } +}; +``` + +When combining with the [`output.library`](/configuration/output#output-library) option: If an array is passed only the last item is exported. + + +# Output + +The top-level `output` key contains set of options instructing webpack on how and where it should output your bundles, assets and anything else you bundle or load with webpack. + + +## `output.auxiliaryComment` + +`string` `object` + +When used in tandem with [`output.library`](#output-library) and [`output.libraryTarget`](#output-librarytarget), this option allows users to insert comments within the export wrapper. To insert the same comment for each `libraryTarget` type, set `auxiliaryComment` to a string: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + output: { + library: 'someLibName', + libraryTarget: 'umd', + filename: 'someLibName.js', + auxiliaryComment: 'Test Comment' + } +}; +``` + +which will yield the following: + +__webpack.config.js__ + +```javascript +(function webpackUniversalModuleDefinition(root, factory) { + // Test Comment + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require('lodash')); + // Test Comment + else if(typeof define === 'function' && define.amd) + define(['lodash'], factory); + // Test Comment + else if(typeof exports === 'object') + exports['someLibName'] = factory(require('lodash')); + // Test Comment + else + root['someLibName'] = factory(root['_']); +})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) { + // ... +}); +``` + +For fine-grained control over each `libraryTarget` comment, pass an object: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + output: { + //... + auxiliaryComment: { + root: 'Root Comment', + commonjs: 'CommonJS Comment', + commonjs2: 'CommonJS2 Comment', + amd: 'AMD Comment' + } + } +}; +``` + + +## `output.chunkFilename` + +`string` + +This option determines the name of non-entry chunk files. See [`output.filename`](#output-filename) option for details on the possible values. + +Note that these filenames need to be generated at runtime to send the requests for chunks. Because of this, placeholders like `[name]` and `[chunkhash]` need to add a mapping from chunk id to placeholder value to the output bundle with the webpack runtime. This increases the size and may invalidate the bundle when placeholder value for any chunk changes. + +By default `[id].js` is used or a value inferred from [`output.filename`](#output-filename) (`[name]` is replaced with `[id]` or `[id].` is prepended). + + +## `output.chunkLoadTimeout` + +`integer` + +Number of milliseconds before chunk request expires, defaults to 120 000. This option is supported since webpack 2.6.0. + + +## `output.crossOriginLoading` + +`boolean` `string` + +Only used when [`target`](/configuration/target) is web, which uses JSONP for loading on-demand chunks, by adding script tags. + +Enable [cross-origin](https://developer.mozilla.org/en/docs/Web/HTML/Element/script#attr-crossorigin) loading of chunks. The following values are accepted... + +`crossOriginLoading: false` - Disable cross-origin loading (default) + +`crossOriginLoading: 'anonymous'` - Enable cross-origin loading __without credentials__ + +`crossOriginLoading: 'use-credentials'` - Enable cross-origin loading __with credentials__ + + +## `output.jsonpScriptType` + +`string` + +Allows customization of the `script` type webpack injects `script` tags into the DOM to download async chunks. The following options are available: + +- `'text/javascript'` (default) +- `'module'`: Use with ES6 ready code. + + +## `output.devtoolFallbackModuleFilenameTemplate` + +`string | function(info)` + +A fallback used when the template string or function above yields duplicates. + +See [`output.devtoolModuleFilenameTemplate`](#output-devtoolmodulefilenametemplate). + + +## `output.devtoolLineToLine` + +`boolean | object` + +> Avoid using this option as it is __deprecated__ and will soon be removed. + +Enables line to line mapping for all or some modules. This produces a simple source map where each line of the generated source is mapped to the same line of the original source. This is a performance optimization and should only be used if all input lines match generated lines. + +Pass a boolean to enable or disable this feature for all modules (defaults to `false`). An object with `test`, `include`, `exclude` is also allowed. For example, to enable this feature for all javascript files within a certain directory: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + output: { + devtoolLineToLine: { test: /\.js$/, include: 'src/utilities' } + } +}; +``` + + +## `output.devtoolModuleFilenameTemplate` + +`string | function(info)` + +This option is only used when [`devtool`](/configuration/devtool) uses an options which requires module names. + +Customize the names used in each source map's `sources` array. This can be done by passing a template string or function. For example, when using `devtool: 'eval'`, this is the default: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + output: { + devtoolModuleFilenameTemplate: 'webpack://[namespace]/[resource-path]?[loaders]' + } +}; +``` + +The following substitutions are available in template strings (via webpack's internal [`ModuleFilenameHelpers`](https://github.com/webpack/webpack/blob/master/lib/ModuleFilenameHelpers.js)): + +| Template | Description | +| ------------------------ | ----------- | +| [absolute-resource-path] | The absolute filename | +| [all-loaders] | Automatic and explicit loaders and params up to the name of the first loader | +| [hash] | The hash of the module identifier | +| [id] | The module identifier | +| [loaders] | Explicit loaders and params up to the name of the first loader | +| [resource] | The path used to resolve the file and any query params used on the first loader | +| [resource-path] | The path used to resolve the file without any query params | +| [namespace] | The modules namespace. This is usually the library name when building as a library, empty otherwise | + +When using a function, the same options are available camel-cased via the `info` parameter: + +```javascript +module.exports = { + //... + output: { + devtoolModuleFilenameTemplate: info => { + return `webpack:///${info.resourcePath}?${info.loaders}`; + } + } +}; +``` + +If multiple modules would result in the same name, [`output.devtoolFallbackModuleFilenameTemplate`](#output-devtoolfallbackmodulefilenametemplate) is used instead for these modules. + + +## `output.devtoolNamespace` + +`string` + +This option determines the modules namespace used with the [`output.devtoolModuleFilenameTemplate`](#output-devtoolmodulefilenametemplate). When not specified, it will default to the value of: [`output.library`](#output-library). It's used to prevent source file path collisions in source maps when loading multiple libraries built with webpack. + +For example, if you have 2 libraries, with namespaces `library1` and `library2`, which both have a file `./src/index.js` (with potentially different contents), they will expose these files as `webpack://library1/./src/index.js` and `webpack://library2/./src/index.js`. + + +## `output.filename` + +`string` `function` + +This option determines the name of each output bundle. The bundle is written to the directory specified by the [`output.path`](#output-path) option. + +For a single [`entry`](/configuration/entry-context#entry) point, this can be a static name. + +__webpack.config.js__ + +```javascript +module.exports = { + //... + output: { + filename: 'bundle.js' + } +}; +``` + +However, when creating multiple bundles via more than one entry point, code splitting, or various plugins, you should use one of the following substitutions to give each bundle a unique name... + +Using entry name: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + output: { + filename: '[name].bundle.js' + } +}; +``` + +Using internal chunk id: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + output: { + filename: '[id].bundle.js' + } +}; +``` + +Using the unique hash generated for every build: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + output: { + filename: '[name].[hash].bundle.js' + } +}; +``` + +Using hashes based on each chunks' content: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + output: { + filename: '[chunkhash].bundle.js' + } +}; +``` + +Using hashes generated for extracted content: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + output: { + filename: '[contenthash].bundle.css' + } +}; +``` + +Using function to return the filename: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + output: { + filename: (chunkData) => { + return chunkData.chunk.name === 'main' ? '[name].js': '[name]/[name].js'; + }, + } +}; +``` + +Make sure to read the [Caching guide](/guides/caching) for details. There are more steps involved than just setting this option. + +Note this option is called filename but you are still allowed to use something like `'js/[name]/bundle.js'` to create a folder structure. + +Note this option does not affect output files for on-demand-loaded chunks. For these files the [`output.chunkFilename`](#output-chunkfilename) option is used. Files created by loaders also aren't affected. In this case you would have to try the specific loader's available options. + +The following substitutions are available in template strings (via webpack's internal [`TemplatedPathPlugin`](https://github.com/webpack/webpack/blob/master/lib/TemplatedPathPlugin.js)): + +| Template | Description | +| ----------- | ----------------------------------------------------------------------------------- | +| [hash] | The hash of the module identifier | +| [chunkhash] | The hash of the chunk content | +| [name] | The module name | +| [id] | The module identifier | +| [query] | The module query, i.e., the string following `?` in the filename | +| [function] | The function, which can return filename [string] | + +The lengths of `[hash]` and `[chunkhash]` can be specified using `[hash:16]` (defaults to 20). Alternatively, specify [`output.hashDigestLength`](#output-hashdigestlength) to configure the length globally. + +If using a function for this option, the function will be passed an object containing the substitutions in the table above. + +T> When using the [`ExtractTextWebpackPlugin`](/plugins/extract-text-webpack-plugin), use `[contenthash]` to obtain a hash of the extracted file (neither `[hash]` nor `[chunkhash]` work). + + +## `output.hashDigest` + +The encoding to use when generating the hash, defaults to `'hex'`. All encodings from Node.JS' [`hash.digest`](https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding) are supported. Using `'base64'` for filenames might be problematic since it has the character `/` in its alphabet. Likewise `'latin1'` could contain any character. + + +## `output.hashDigestLength` + +The prefix length of the hash digest to use, defaults to `20`. + + +## `output.hashFunction` + +`string|function` + +The hashing algorithm to use, defaults to `'md4'`. All functions from Node.JS' [`crypto.createHash`](https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm_options) are supported. Since `4.0.0-alpha2`, the `hashFunction` can now be a constructor to a custom hash function. You can provide a non-crypto hash function for performance reasons. + +```javascript +module.exports = { + //... + output: { + hashFunction: require('metrohash').MetroHash64 + } +}; +``` + +Make sure that the hashing function will have `update` and `digest` methods available. + +## `output.hashSalt` + +An optional salt to update the hash via Node.JS' [`hash.update`](https://nodejs.org/api/crypto.html#crypto_hash_update_data_inputencoding). + + +## `output.hotUpdateChunkFilename` + +`string` `function` + +Customize the filenames of hot update chunks. See [`output.filename`](#output-filename) option for details on the possible values. + +The only placeholders allowed here are `[id]` and `[hash]`, the default being: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + output: { + hotUpdateChunkFilename: '[id].[hash].hot-update.js' + } +}; +``` + +Here is no need to change it. + + +## `output.hotUpdateFunction` + +`function` + +Only used when [`target`](/configuration/target) is web, which uses JSONP for loading hot updates. + +A JSONP function used to asynchronously load hot-update chunks. + +For details see [`output.jsonpFunction`](#output-jsonpfunction). + + +## `output.hotUpdateMainFilename` + +`string` `function` + +Customize the main hot update filename. See [`output.filename`](#output-filename) option for details on the possible values. + +`[hash]` is the only available placeholder, the default being: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + output: { + hotUpdateMainFilename: '[hash].hot-update.json' + } +}; +``` + +Here is no need to change it. + + +## `output.jsonpFunction` + +`string` + +Only used when [`target`](/configuration/target) is web, which uses JSONP for loading on-demand chunks. + +A JSONP function name used to asynchronously load chunks or join multiple initial chunks (SplitChunksPlugin, AggressiveSplittingPlugin). + +This needs to be changed if multiple webpack runtimes (from different compilation) are used on the same webpage. + +If using the [`output.library`](#output-library) option, the library name is automatically appended. + + +## `output.library` + +`string` or `object` (since webpack 3.1.0; for `libraryTarget: 'umd'`) + +How the value of the `output.library` is used depends on the value of the [`output.libraryTarget`](#output-librarytarget) option; please refer to that section for the complete details. Note that the default option for `output.libraryTarget` is `var`, so if the following configuration option is used: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + output: { + library: 'MyLibrary' + } +}; +``` + +The variable `MyLibrary` will be bound with the return value of your entry file, if the resulting output is included as a script tag in an HTML page. + +W> Note that if an `array` is provided as an `entry` point, only the last module in the array will be exposed. If an `object` is provided, it can be exposed using an `array` syntax (see [this example](https://github.com/webpack/webpack/tree/master/examples/multi-part-library) for details). + +T> Read the [authoring libraries guide](/guides/author-libraries) guide for more information on `output.library` as well as `output.libraryTarget`. + + +## `output.libraryExport` + +`string | string[]` + +Configure which module or modules will be exposed via the `libraryTarget`. It is `undefined` by default, same behaviour will be applied if you set `libraryTarget` to an empty string e.g. `''` it will export the whole (namespace) object. The examples below demonstrate the effect of this config when using `libraryTarget: 'var'`. + +The following configurations are supported: + +`libraryExport: 'default'` - The __default export of your entry point__ will be assigned to the library target: + +```javascript +// if your entry has a default export of `MyDefaultModule` +var MyDefaultModule = _entry_return_.default; +``` + +`libraryExport: 'MyModule'` - The __specified module__ will be assigned to the library target: + +```javascript +var MyModule = _entry_return_.MyModule; +``` + +`libraryExport: ['MyModule', 'MySubModule']` - The array is interpreted as a __path to a module__ to be assigned to the library target: + +```javascript +var MySubModule = _entry_return_.MyModule.MySubModule; +``` + +With the `libraryExport` configurations specified above, the resulting libraries could be utilized as such: + +```javascript +MyDefaultModule.doSomething(); +MyModule.doSomething(); +MySubModule.doSomething(); +``` + + +## `output.libraryTarget` + +`string: 'var'` + +Configure how the library will be exposed. Any one of the following options can be used. Please note that this option works in conjunction with the value assigned to [`output.library`](#output-library). For the following examples, it is assumed that this value is configured as `MyLibrary`. + +T> Note that `_entry_return_` in the example code below is the value returned by the entry point. In the bundle itself, it is the output of the function that is generated by webpack from the entry point. + +### Expose a Variable + +These options assign the return value of the entry point (e.g. whatever the entry point exported) to the name provided by `output.library` at whatever scope the bundle was included at. + +`libraryTarget: 'var'` - (default) When your library is loaded, the __return value of your entry point__ will be assigned to a variable: + +```javascript +var MyLibrary = _entry_return_; + +// In a separate script... +MyLibrary.doSomething(); +``` + +W> When using this option, an empty `output.library` will result in no assignment. + + +`libraryTarget: 'assign'` - This will generate an implied global which has the potential to reassign an existing value (use with caution). + +```javascript +MyLibrary = _entry_return_; +``` + +Be aware that if `MyLibrary` isn't defined earlier your library will be set in global scope. + +W> When using this option, an empty `output.library` will result in a broken output bundle. + + +### Expose Via Object Assignment + +These options assign the return value of the entry point (e.g. whatever the entry point exported) to a specific object under the name defined by `output.library`. + +If `output.library` is not assigned a non-empty string, the default behavior is that all properties returned by the entry point will be assigned to the object as defined for the particular `output.libraryTarget`, via the following code fragment: + +```javascript +(function(e, a) { for(var i in a) { e[i] = a[i]; } }(output.libraryTarget, _entry_return_)); +``` + +W> Note that not setting a `output.library` will cause all properties returned by the entry point to be assigned to the given object; there are no checks against existing property names. + +`libraryTarget: "this"` - The __return value of your entry point__ will be assigned to this under the property named by `output.library`. The meaning of `this` is up to you: + +```javascript +this['MyLibrary'] = _entry_return_; + +// In a separate script... +this.MyLibrary.doSomething(); +MyLibrary.doSomething(); // if this is window +``` + +`libraryTarget: 'window'` - The __return value of your entry point__ will be assigned to the `window` object using the `output.library` value. + +```javascript +window['MyLibrary'] = _entry_return_; + +window.MyLibrary.doSomething(); +``` + + +`libraryTarget: 'global'` - The __return value of your entry point__ will be assigned to the `global` object using the `output.library` value. + +```javascript +global['MyLibrary'] = _entry_return_; + +global.MyLibrary.doSomething(); +``` + + +`libraryTarget: 'commonjs'` - The __return value of your entry point__ will be assigned to the `exports` object using the `output.library` value. As the name implies, this is used in CommonJS environments. + +```javascript +exports['MyLibrary'] = _entry_return_; + +require('MyLibrary').doSomething(); +``` + +### Module Definition Systems + +These options will result in a bundle that comes with a more complete header to ensure compatibility with various module systems. The `output.library` option will take on a different meaning under the following `output.libraryTarget` options. + + +`libraryTarget: 'commonjs2'` - The __return value of your entry point__ will be assigned to the `module.exports`. As the name implies, this is used in CommonJS environments: + +```javascript +module.exports = _entry_return_; + +require('MyLibrary').doSomething(); +``` + +Note that `output.library` is omitted, thus it is not required for this particular `output.libraryTarget`. + +T> Wondering the difference between CommonJS and CommonJS2 is? While they are similar, there are some subtle differences between them that are not usually relevant in the context of webpack. (For further details, please [read this issue](https://github.com/webpack/webpack/issues/1114).) + + +`libraryTarget: 'amd'` - This will expose your library as an AMD module. + +AMD modules require that the entry chunk (e.g. the first script loaded by the ` +``` + +__webpack.config.js__ + +```javascript +module.exports = { + //... + externals: { + jquery: 'jQuery' + } +}; +``` + +This leaves any dependent modules unchanged, i.e. the code shown below will still work: + +```javascript +import $ from 'jquery'; + +$('.my-element').animate(/* ... */); +``` + +The bundle with external dependencies can be used in various module contexts, such as [CommonJS, AMD, global and ES2015 modules](/concepts/modules). The external library may be available in any of these forms: + +- __root__: The library should be available as a global variable (e.g. via a script tag). +- __commonjs__: The library should be available as a CommonJS module. +- __commonjs2__: Similar to the above but where the export is `module.exports.default`. +- __amd__: Similar to `commonjs` but using AMD module system. + +The following syntaxes are accepted... + + +### string + +See the example above. The property name `jquery` indicates that the module `jquery` in `import $ from 'jquery'` should be excluded. In order to replace this module, the value `jQuery` will be used to retrieve a global `jQuery` variable. In other words, when a string is provided it will be treated as `root` (defined above and below). + + +### array + +```javascript +module.exports = { + //... + externals: { + subtract: ['./math', 'subtract'] + } +}; +``` + +`subtract: ['./math', 'subtract']` converts to a parent child construct, where `./math` is the parent module and your bundle only requires the subset under `subtract` variable. + + +### object + +W> An object with `{ root, amd, commonjs, ... }` is only allowed for [`libraryTarget: 'umd'`](/configuration/output/#output-librarytarget). It's not allowed for other library targets. + +```javascript +module.exports = { + //... + externals : { + react: 'react' + }, + + // or + + externals : { + lodash : { + commonjs: 'lodash', + amd: 'lodash', + root: '_' // indicates global variable + } + }, + + // or + + externals : { + subtract : { + root: ['math', 'subtract'] + } + } +}; +``` + +This syntax is used to describe all the possible ways that an external library can be available. `lodash` here is available as `lodash` under AMD and CommonJS module systems but available as `_` in a global variable form. `subtract` here is available via the property `subtract` under the global `math` object (e.g. `window['math']['subtract']`). + + +### function + +It might be useful to define your own function to control the behavior of what you want to externalize from webpack. [webpack-node-externals](https://www.npmjs.com/package/webpack-node-externals), for example, excludes all modules from the `node_modules` directory and provides some options to, for example, whitelist packages. + +It basically comes down to this: + +```javascript +module.exports = { + //... + externals: [ + function(context, request, callback) { + if (/^yourregex$/.test(request)){ + return callback(null, 'commonjs ' + request); + } + callback(); + } + ] +}; +``` + +The `'commonjs ' + request` defines the type of module that needs to be externalized. + + +### regex + +Every dependency that matches the given regular expression will be excluded from the output bundles. + +```javascript +module.exports = { + //... + externals: /^(jquery|\$)$/i +}; +``` + +In this case any dependency named `jQuery`, capitalized or not, or `$` would be externalized. + +### Combining syntaxes + +Sometimes you may want to use a combination of the above syntaxes. This can be done in the following manner: + +```javascript +module.exports = { + //... + externals: [ + { + // String + react: 'react', + // Object + lodash : { + commonjs: 'lodash', + amd: 'lodash', + root: '_' // indicates global variable + }, + // Array + subtract: ['./math', 'subtract'] + }, + // Function + function(context, request, callback) { + if (/^yourregex$/.test(request)){ + return callback(null, 'commonjs ' + request); + } + callback(); + }, + // Regex + /^(jquery|\$)$/i + ] +}; +``` + +For more information on how to use this configuration, please refer to the article on [how to author a library](/guides/author-libraries). + + +# Node + +These options configure whether to polyfill or mock certain [Node.js globals](https://nodejs.org/docs/latest/api/globals.html) and modules. This allows code originally written for the Node.js environment to run in other environments like the browser. + +This feature is provided by webpack's internal [`NodeStuffPlugin`](https://github.com/webpack/webpack/blob/master/lib/NodeStuffPlugin.js) plugin. If the target is "web" (default) or "webworker", the [`NodeSourcePlugin`](https://github.com/webpack/webpack/blob/master/lib/node/NodeSourcePlugin.js) plugin is also activated. + + +## `node` + +`object` + +This is an object where each property is the name of a Node global or module and each value may be one of the following... + +- `true`: Provide a polyfill. +- `"mock"`: Provide a mock that implements the expected interface but has little or no functionality. +- `"empty"`: Provide an empty object. +- `false`: Provide nothing. Code that expects this object may crash with a `ReferenceError`. Code that attempts to import the module using `require('modulename')` may trigger a `Cannot find module "modulename"` error. + +W> Not every Node global supports all four options. The compiler will throw an error for property-value combinations that aren't supported (e.g. `process: 'empty'`). See the sections below for more details. + +These are the defaults: + +```js +module.exports = { + //... + node: { + console: false, + global: true, + process: true, + __filename: 'mock', + __dirname: 'mock', + Buffer: true, + setImmediate: true + + // See "Other node core libraries" for additional options. + } +}; +``` + +Since webpack 3.0.0, the `node` option may be set to `false` to completely turn off the `NodeStuffPlugin` and `NodeSourcePlugin` plugins. + + +## `node.console` + +`boolean | "mock"` + +Default: `false` + +The browser provides a `console` object with a very similar interface to the Node.js `console`, so a polyfill is generally not needed. + + +## `node.process` + +`boolean | "mock"` + +Default: `true` + + +## `node.global` + +`boolean` + +Default: `true` + +See [the source](https://github.com/webpack/webpack/blob/master/buildin/global.js) for the exact behavior of this object. + + +## `node.__filename` + +`boolean | "mock"` + +Default: `"mock"` + +Options: + +- `true`: The filename of the __input__ file relative to the [`context` option](https://webpack.js.org/configuration/entry-context/#context). +- `false`: The regular Node.js `__filename` behavior. The filename of the __output__ file when run in a Node.js environment. +- `"mock"`: The fixed value `"index.js"`. + + +## `node.__dirname` + +`boolean | "mock"` + +Default: `"mock"` + +Options: + +- `true`: The dirname of the __input__ file relative to the [`context` option](https://webpack.js.org/configuration/entry-context/#context). +- `false`: The regular Node.js `__dirname` behavior. The dirname of the __output__ file when run in a Node.js environment. +- `"mock"`: The fixed value `"/"`. + + +## `node.Buffer` + +`boolean | "mock"` + +Default: `true` + + +## `node.setImmediate` + +`boolean | "mock" | "empty"` + +Default: `true` + + +## Other node core libraries + +`boolean | "mock" | "empty"` + +W> This option is only activated (via `NodeSourcePlugin`) when the target is unspecified, "web" or "webworker". + +Polyfills for Node.js core libraries from [`node-libs-browser`](https://github.com/webpack/node-libs-browser) are used if available, when the `NodeSourcePlugin` plugin is enabled. See the list of [Node.js core libraries and their polyfills](https://github.com/webpack/node-libs-browser#readme). + +By default, webpack will polyfill each library if there is a known polyfill or do nothing if there is not one. In the latter case, webpack will behave as if the module name was configured with the `false` value. + +T> To import a built-in module, use [`__non_webpack_require__`](/api/module-variables/#__non_webpack_require__-webpack-specific-), i.e. `__non_webpack_require__('modulename')` instead of `require('modulename')`. + +Example: + +```js +module.exports = { + //... + node: { + dns: 'mock', + fs: 'empty', + path: true, + url: false + } +}; +``` + + +# Performance + +These options allows you to control how webpack notifies you of assets and entry points that exceed a specific file limit. +This feature was inspired by the idea of [webpack Performance Budgets](https://github.com/webpack/webpack/issues/3216). + +## `performance` + +`object` + +Configure how performance hints are shown. For example if you have an asset that is over 250kb, webpack will emit a warning notifying you of this. + + +## `performance.hints` + +`false | "error" | "warning"` + +Turns hints on/off. In addition, tells webpack to throw either an error or a warning when hints are found. This property is set to `"warning"` by default. + +Given an asset is created that is over 250kb: + +```js +module.exports = { + //... + performance: { + hints: false + } +}; +``` + +No hint warnings or errors are shown. + +```js +module.exports = { + //... + performance: { + hints: 'warning' + } +}; +``` + +A warning will be displayed notifying you of a large asset. We recommend something like this for development environments. + +```js +module.exports = { + //... + performance: { + hints: 'error' + } +}; +``` + +An error will be displayed notifying you of a large asset. We recommend using `hints: "error"` during production builds to help prevent deploying production bundles that are too large, impacting webpage performance. + +## `performance.maxEntrypointSize` + +`int` + +An entry point represents all assets that would be utilized during initial load time for a specific entry. This option controls when webpack should emit performance hints based on the maximum entry point size. The default value is `250000` (bytes). + +```js +module.exports = { + //... + performance: { + maxEntrypointSize: 400000 + } +}; +``` + +## `performance.maxAssetSize` + +`int` + +An asset is any emitted file from webpack. This option controls when webpack emits a performance hint based on individual asset size. The default value is `250000` (bytes). + + +```js +module.exports = { + //... + performance: { + maxAssetSize: 100000 + } +}; +``` + +## `performance.assetFilter` + +`Function` + +This property allows webpack to control what files are used to calculate performance hints. The default function is seen below: + +```js +function assetFilter(assetFilename) { + return !(/\.map$/.test(assetFilename)); +} +``` + +You can override this property by passing your own function in: + +```js +module.exports = { + //... + performance: { + assetFilter: function(assetFilename) { + return assetFilename.endsWith('.js'); + } + } +}; +``` + +The example above will only give you performance hints based on `.js` files. + + +# Stats + +The `stats` option lets you precisely control what bundle information gets displayed. This can be a nice middle ground if you don't want to use `quiet` or `noInfo` because you want some bundle information, but not all of it. + +T> For webpack-dev-server, this property needs to be in the `devServer` object. + +W> This option does not have any effect when using the Node.js API. + +## `stats` + +`object` `string` + +There are some presets available to use as a shortcut. Use them like this: + +```js +module.exports = { + //... + stats: 'errors-only' +}; +``` + +| Preset | Alternative | Description | +|--------|-------------|-------------| +| `"errors-only"` | _none_ | Only output when errors happen | +| `"minimal"` | _none_ | Only output when errors or new compilation happen | +| `"none"` | `false` | Output nothing | +| `"normal"` | `true` | Standard output | +| `"verbose"` | _none_ | Output everything | + +For more granular control, it is possible to specify exactly what information you want. Please note that all of the options in this object are optional. + + + +```js +module.exports = { + //... + stats: { + // fallback value for stats options when an option is not defined (has precedence over local webpack defaults) + all: undefined, + + // Add asset Information + assets: true, + + // Sort assets by a field + // You can reverse the sort with `!field`. + // Some possible values: 'id' (default), 'name', 'size', 'chunks', 'failed', 'issuer' + // For a complete list of fields see the bottom of the page + assetsSort: "field", + + // Add build date and time information + builtAt: true, + + // Add information about cached (not built) modules + cached: true, + + // Show cached assets (setting this to `false` only shows emitted files) + cachedAssets: true, + + // Add children information + children: true, + + // Add chunk information (setting this to `false` allows for a less verbose output) + chunks: true, + + // Add namedChunkGroups information + chunkGroups: true, + + // Add built modules information to chunk information + chunkModules: true, + + // Add the origins of chunks and chunk merging info + chunkOrigins: true, + + // Sort the chunks by a field + // You can reverse the sort with `!field`. Default is `id`. + // Some other possible values: 'name', 'size', 'chunks', 'failed', 'issuer' + // For a complete list of fields see the bottom of the page + chunksSort: "field", + + // Context directory for request shortening + context: "../src/", + + // `webpack --colors` equivalent + colors: false, + + // Display the distance from the entry point for each module + depth: false, + + // Display the entry points with the corresponding bundles + entrypoints: false, + + // Add --env information + env: false, + + // Add errors + errors: true, + + // Add details to errors (like resolving log) + errorDetails: true, + + // Exclude assets from being displayed in stats + // This can be done with a String, a RegExp, a Function getting the assets name + // and returning a boolean or an Array of the above. + excludeAssets: "filter" | /filter/ | (assetName) => true | false | + ["filter"] | [/filter/] | [(assetName) => true|false], + + // Exclude modules from being displayed in stats + // This can be done with a String, a RegExp, a Function getting the modules source + // and returning a boolean or an Array of the above. + excludeModules: "filter" | /filter/ | (moduleSource) => true | false | + ["filter"] | [/filter/] | [(moduleSource) => true|false], + + // See excludeModules + exclude: "filter" | /filter/ | (moduleSource) => true | false | + ["filter"] | [/filter/] | [(moduleSource) => true|false], + + // Add the hash of the compilation + hash: true, + + // Set the maximum number of modules to be shown + maxModules: 15, + + // Add built modules information + modules: true, + + // Sort the modules by a field + // You can reverse the sort with `!field`. Default is `id`. + // Some other possible values: 'name', 'size', 'chunks', 'failed', 'issuer' + // For a complete list of fields see the bottom of the page + modulesSort: "field", + + // Show dependencies and origin of warnings/errors (since webpack 2.5.0) + moduleTrace: true, + + // Show performance hint when file size exceeds `performance.maxAssetSize` + performance: true, + + // Show the exports of the modules + providedExports: false, + + // Add public path information + publicPath: true, + + // Add information about the reasons why modules are included + reasons: true, + + // Add the source code of modules + source: false, + + // Add timing information + timings: true, + + // Show which exports of a module are used + usedExports: false, + + // Add webpack version information + version: true, + + // Add warnings + warnings: true, + + // Filter warnings to be shown (since webpack 2.4.0), + // can be a String, Regexp, a function getting the warning and returning a boolean + // or an Array of a combination of the above. First match wins. + warningsFilter: "filter" | /filter/ | ["filter", /filter/] | (warning) => true|false + } +} +``` + +If you want to use one of the pre-defined behaviours e.g. `'minimal'` but still override one or more of the rules, see [the source code](https://github.com/webpack/webpack/blob/master/lib/Stats.js#L1394-L1401). You would want to copy the configuration options from `case 'minimal': ...` and add your additional rules while providing an object to `stats`. + +__webpack.config.js__ + +```javascript +module.exports = { + //.. + stats: { + // copied from `'minimal'` + all: false, + modules: true, + maxModules: 0, + errors: true, + warnings: true, + // our additional options + moduleTrace: true, + errorDetails: true + } +}; +``` + +### Sorting fields + +For `assetsSort`, `chunksSort` and `moduleSort` there are several possible fields that you can sort items by: + +- `id` is the item's id; +- `name` - a item's name that was assigned to it upon importing; +- `size` - a size of item in bytes; +- `chunks` - what chunks the item originates from (for example, if there are multiple subchunks for one chunk - the subchunks will be grouped together according to their main chunk); +- `errors` - amount of errors in items; +- `warnings` - amount of warnings in items; +- `failed` - whether the item has failed compilation; +- `cacheable` - whether the item is cacheable; +- `built` - whether the asset has been built; +- `prefetched` - whether the asset will be prefetched; +- `optional` - whether the asset is optional; +- `identifier` - identifier of the item; +- `index` - item's processing index; +- `index2` +- `profile` +- `issuer` - an identifier of the issuer; +- `issuerId` - an id of the issuer; +- `issuerName` - a name of the issuer; +- `issuerPath` - a full issuer object. There's no real need to sort by this field; + + +# Other Options + + +These are the remaining configuration options supported by webpack. + +W> Help Wanted: This page is still a work in progress. If you are familiar with any of the options for which the description or examples are incomplete, please create an issue and submit a PR at the [docs repo](https://github.com/webpack/webpack.js.org)! + + +## `amd` + +`object` + +Set the value of `require.amd` or `define.amd`: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + amd: { + jQuery: true + } +}; +``` + +Certain popular modules written for AMD, most notably jQuery versions 1.7.0 to 1.9.1, will only register as an AMD module if the loader indicates it has taken [special allowances](https://github.com/amdjs/amdjs-api/wiki/jQuery-and-AMD) for multiple versions being included on a page. + +The allowances were the ability to restrict registrations to a specific version or to support different sandboxes with different defined modules. + +This option allows you to set the key your module looks for to a truthy value. +As it happens, the AMD support in webpack ignores the defined name anyways. + + +## `bail` + +`boolean` + +Fail out on the first error instead of tolerating it. By default webpack will log these errors in red in the terminal, as well as the browser console when using HMR, but continue bundling. To enable it: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + bail: true +}; +``` + +This will force webpack to exit its bundling process. + + +## `cache` + +`boolean` `object` + +Cache the generated webpack modules and chunks to improve build speed. Caching is enabled by default while in watch mode. To disable caching simply pass: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + cache: false +}; +``` + +If an object is passed, webpack will use this object for caching. Keeping a reference to this object will allow one to share the same cache between compiler calls: + +__webpack.config.js__ + +```javascript +let SharedCache = {}; + +module.exports = { + //... + cache: SharedCache +}; +``` + +W> Don't share the cache between calls with different options. + +?> Elaborate on the warning and example - calls with different configuration options? + + +## `loader` + +`object` + +Expose custom values into the loader context. + +?> Add an example... + + +## `parallelism` + +`number` + +Limit the number of parallel processed modules. Can be used to fine tune performance or to get more reliable profiling results. + + +## `profile` + +`boolean` + +Capture a "profile" of the application, including statistics and hints, which can then be dissected using the [Analyze](https://webpack.github.io/analyse/) tool. + +T> Use the [StatsPlugin](https://www.npmjs.com/package/stats-webpack-plugin) for more control over the generated profile. + +T> Combine with `parallelism: 1` for better results. + + +## `recordsPath` + +`string` + +Use this option to generate a JSON file containing webpack "records" -- pieces of data used to store module identifiers across multiple builds. You can use this file to track how modules change between builds. To generate one, simply specify a location: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + recordsPath: path.join(__dirname, 'records.json') +}; +``` + +Records are particularly useful if you have a complex setup that leverages [Code Splitting](/guides/code-splitting). The data can be used to ensure the split bundles are achieving the [caching](/guides/caching) behavior you need. + +T> Note that although this file is generated by the compiler, you may still want to track it in source control to keep a history of how it has changed over time. + +W> Setting `recordsPath` will essentially set `recordsInputPath` and `recordsOutputPath` to the same location. This is usually all that's necessary unless you decide to change the name of the file containing the records. See below for an example. + + +## `recordsInputPath` + +`string` + +Specify the file from which to read the last set of records. This can be used to rename a records file. See the example below. + + +## `recordsOutputPath` + +`string` + +Specify where the records should be written. The following example shows how you might use this option in combination with `recordsInputPath` to rename a records file: + +__webpack.config.js__ + +```javascript +module.exports = { + //... + recordsInputPath: path.join(__dirname, 'records.json'), + recordsOutputPath: path.join(__dirname, 'newRecords.json') +}; +``` + + +## `name` + +`string` + +Name of the configuration. Used when loading multiple configurations. + +__webpack.config.js__ + +```javascript +module.exports = { + //... + name: 'admin-app' +}; +``` diff --git a/src/content/contribute/_contribute_all.md b/src/content/contribute/_contribute_all.md new file mode 100644 index 000000000000..beab316a12a7 --- /dev/null +++ b/src/content/contribute/_contribute_all.md @@ -0,0 +1,979 @@ + + +# Contribute + +The people who contribute to webpack do so for the love of open source, our users and ecosystem, and most importantly, pushing the web forward together. Because of our [Open Collective](https://opencollective.com/webpack) model for funding and transparency, we are able to funnel support and funds through contributors, dependent projects, and the contributor and core teams. To make a donation, simply click the button below... + + + +But what is the return on the investment? + + +## Developers + +The biggest core feature we'd like to provide is enjoyable development experience. Developers like you can help by contributing to rich and vibrant documentation, issuing pull requests to help us cover niche use cases, and to help sustain what you love about webpack. + +### How Can I Help? + +Anybody can help by doing any of the following: + +- Ask your employer to use webpack in projects. +- Help us write and maintain the content on this site (see the [writer's guide](/writers-guide)). +- Contribute to the [core repository](https://github.com/webpack/webpack). +- Become a backer or sponsor on [open collective](https://opencollective.com/webpack#support). + +### Encouraging Employers + +You can ask your employer to improve your workflow by leveraging webpack: an all-in-one tool for fonts, images and image optimization, and json. Explain to them how webpack will attempt to bundle your code and assets the best it can for the smallest file size, leading to speedier sites and applications. + +### Your Contributions + +Contributing to webpack is not contributing to an exclusive club. You as a developer are contributing to the overall health of downstream projects. Hundreds, if not thousands, of projects depend on webpack and contributing will make the ecosystem better for all users. + +The remainder of this section of the site is dedicated to developers such as yourself who would like to become a part of our ever-growing community: + +- [Writing a Loader](./writing-a-loader) +- [Writing a Plugin](./writing-a-plugin) +- [Plugin Patterns](./plugin-patterns) +- [Release Process](./release-process) + + +## Executives + +CTO's, VPs, and owners can help too! + + + +webpack is an all-in-one tool for bundling your code. It can handle fonts, images, data and more with the help of community-driven plugins and loaders. Having all of your assets be handled by one tool is immensely helpful, as you or your team can spend less time making sure a machine with many moving parts is working correctly and more time building your product. + +### Sponsorship + +Aside from monetary assistance, companies can support webpack by: + +- Providing developers that are not actively working on a project. +- Contributing computing power for improved CI and regression testing. + +You can also encourage your developers to contribute to the ecosystem by open-sourcing webpack loaders, plugins and other utilities. And, as mentioned above, we would greatly appreciate any help increasing our CI/CD infrastructure. + +### Anyone Else + +To anyone else who is interested in helping our mission -- e.g. venture capitalists, government entities, digital agencies, etc. -- we would love for you to work with us, one of the top npm packages, to improve your product! Please don't hesitate to reach out with questions. + + + + +# Writer's Guide + +The following sections contain all you need to know about editing and formatting the content within this site. Make sure to do some research before starting your edits or additions. Sometimes the toughest part is finding where the content should live and determining whether or not it already exists. + + +## Process + +1. Check related issue if an article links to one. +2. Hit `edit` and expand on the structure. +3. PR changes. + + +## YAML Frontmatter + +Each article contains a small section at the top written in [YAML Frontmatter](https://jekyllrb.com/docs/frontmatter/): + +``` yaml +--- +title: My Article +group: My Sub-Section +sort: 3 +contributors: + - [github username] +related: + - title: Title of Related Article + url: [url of related article] +--- +``` + +Let's break these down: + +- `title`: The name of the article. +- `group`: The name of the sub-section +- `sort`: The order of the article within its section (or) sub-section if it is present. +- `contributors`: A list of GitHub usernames who have contributed to this article. +- `related`: Any related reading or useful examples. + +Note that `related` will generate a __Further Reading__ section at the bottom of the page and `contributors` will yield a __Contributors__ section below it. If you edit an article and would like recognition, don't hesitate to add your GitHub username to the `contributors` list. + + +## Article Structure + +1. Brief Introduction - a paragraph or two so you get the basic idea about the what and why. +2. Outline Remaining Content – how the content will be presented. +3. Main Content - tell what you promised to tell. +4. Conclusion - tell what you told and recap the main points. + + +## Typesetting + +- webpack should always be written in lower-case letters. Even at the beginning of a sentence. ([source](https://github.com/webpack/media#name)) +- loaders are enclosed in backticks and [kebab-cased](https://en.wikipedia.org/w/index.php?title=Kebab_case): `css-loader`, `ts-loader`, … +- plugins are enclosed in backticks and [camel-cased](https://en.wikipedia.org/wiki/Camel_case): `BannerPlugin`, `NpmInstallWebpackPlugin`, … +- Use "webpack 2" to refer to a specific webpack version (~~"webpack v2"~~) +- Use ES5; ES2015, ES2016, … to refer to the ECMAScript standards (~~ES6~~, ~~ES7~~) + + +## Formatting + +### Code + +__Syntax: \`\`\`javascript … \`\`\`__ + +```javascript +function foo () { + return 'bar'; +} + +foo(); +``` + +### Lists + +- Boo +- Foo +- Zoo + +Lists should be ordered alphabetically. + +### Tables + +Parameter | Explanation | Input Type | Default Value +----------- | ------------------------------------------------ | ---------- |-------------- +--debug | Switch loaders to debug mode | boolean | false +--devtool | Define source map type for the bundled resources | string | - +--progress | Print compilation progress in percentage | boolean | false + +Tables should also be ordered alphabetically. + +### Configuration Properties + +The [configuration](/configuration) properties should be ordered alphabetically as well: + +- `devServer.compress` +- `devServer.contentBase` +- `devServer.hot` + +### Quotes + +#### Blockquote + +__Syntax: \>__ + +> This is a blockquote. + +#### Tip + +__Syntax: T\>__ + +T> This is a tip. + +__Syntax: W\>__ + +W> This is a warning. + +__Syntax: ?\>__ + +?> This is a todo. + + +# Writing a Loader + +A loader is a node module that exports a function. This function is called when a resource should be transformed by this loader. The given function will have access to the [Loader API](/api/loaders/) using the `this` context provided to it. + + +## Setup + +Before we dig into the different types of loaders, their usage, and examples, let's take a look at the three ways you can develop and test a loader locally. + +To test a single loader, you can simply use `path` to `resolve` a local file within a rule object: + +__webpack.config.js__ + +```js +module.exports = { + //... + module: { + rules: [ + { + test: /\.js$/, + use: [ + { + loader: path.resolve('path/to/loader.js'), + options: {/* ... */} + } + ] + } + ] + } +}; +``` + +To test multiple, you can utilize the `resolveLoader.modules` configuration to update where webpack will search for loaders. For example, if you had a local `/loaders` directory in your project: + +__webpack.config.js__ + +```js +module.exports = { + //... + resolveLoader: { + modules: [ + 'node_modules', + path.resolve(__dirname, 'loaders') + ] + } +}; +``` + +Last but not least, if you've already created a separate repository and package for your loader, you could [`npm link`](https://docs.npmjs.com/cli/link) it to the project in which you'd like to test it out. + + +## Simple Usage + +When a single loader is applied to the resource, the loader is called with only one parameter -- a string containing the content of the resource file. + +Synchronous loaders can simply `return` a single value representing the transformed module. In more complex cases, the loader can return any number of values by using the `this.callback(err, values...)` function. Errors are either passed to the `this.callback` function or thrown in a sync loader. + +The loader is expected to give back one or two values. The first value is a resulting JavaScript code as string or buffer. The second optional value is a SourceMap as JavaScript object. + + +## Complex Usage + +When multiple loaders are chained, it is important to remember that they are executed in reverse order -- either right to left or bottom to top depending on array format. + +- The last loader, called first, will be passed the contents of the raw resource. +- The first loader, called last, is expected to return JavaScript and an optional source map. +- The loaders in between will be executed with the result(s) of the previous loader in the chain. + +So, in the following example, the `foo-loader` would be passed the raw resource and the `bar-loader` would receive the output of the `foo-loader` and return the final transformed module and a source map if necessary. + +__webpack.config.js__ + +```js +module.exports = { + //... + module: { + rules: [ + { + test: /\.js/, + use: [ + 'bar-loader', + 'foo-loader' + ] + } + ] + } +}; +``` + + +## Guidelines + +The following guidelines should be followed when writing a loader. They are ordered in terms of importance and some only apply in certain scenarios, read the detailed sections that follow for more information. + +- Keep them __simple__. +- Utilize __chaining__. +- Emit __modular__ output. +- Make sure they're __stateless__. +- Employ __loader utilities__. +- Mark __loader dependencies__. +- Resolve __module dependencies__. +- Extract __common code__. +- Avoid __absolute paths__. +- Use __peer dependencies__. + +### Simple + +Loaders should do only a single task. This not only makes the job of maintaining each loader easier, but also allows them to be chained for usage in more scenarios. + +### Chaining + +Take advantage of the fact that loaders can be chained together. Instead of writing a single loader that tackles five tasks, write five simpler loaders that divide this effort. Isolating them not only keeps each individual loader simple, but may allow for them to be used for something you hadn't thought of originally. + +Take the case of rendering a template file with data specified via loader options or query parameters. It could be written as a single loader that compiles the template from source, executes it and returns a module that exports a string containing the HTML code. However, in accordance with guidelines, a simple `apply-loader` exists that can be chained with other open source loaders: + +- `jade-loader`: Convert template to a module that exports a function. +- `apply-loader`: Executes the function with loader options and returns raw HTML. +- `html-loader`: Accepts HTML and outputs a valid JavaScript module. + +T> The fact that loaders can be chained also means they don't necessarily have to output JavaScript. As long as the next loader in the chain can handle its output, the loader can return any type of module. + +### Modular + +Keep the output modular. Loader generated modules should respect the same design principles as normal modules. + +### Stateless + +Make sure the loader does not retain state between module transformations. Each run should always be independent of other compiled modules as well as previous compilations of the same module. + +### Loader Utilities + +Take advantage of the [`loader-utils`](https://github.com/webpack/loader-utils) package. It provides a variety of useful tools but one of the most common is retrieving the options passed to the loader. Along with `loader-utils`, the [`schema-utils`](https://github.com/webpack-contrib/schema-utils) package should be used for consistent JSON Schema based validation of loader options. Here's a brief example that utilizes both: + +__loader.js__ + +```js +import { getOptions } from 'loader-utils'; +import validateOptions from 'schema-utils'; + +const schema = { + type: 'object', + properties: { + test: { + type: 'string' + } + } +}; + +export default function(source) { + const options = getOptions(this); + + validateOptions(schema, options, 'Example Loader'); + + // Apply some transformations to the source... + + return `export default ${ JSON.stringify(source) }`; +} +``` + +### Loader Dependencies + +If a loader uses external resources (i.e. by reading from filesystem), they __must__ indicate it. This information is used to invalidate cacheable loaders and recompile in watch mode. Here's a brief example of how to accomplish this using the `addDependency` method: + +__loader.js__ + +```js +import path from 'path'; + +export default function(source) { + var callback = this.async(); + var headerPath = path.resolve('header.js'); + + this.addDependency(headerPath); + + fs.readFile(headerPath, 'utf-8', function(err, header) { + if(err) return callback(err); + callback(null, header + '\n' + source); + }); +} +``` + +### Module Dependencies + +Depending on the type of module, there may be a different schema used to specify dependencies. In CSS for example, the `@import` and `url(...)` statements are used. These dependencies should be resolved by the module system. + +This can be done in one of two ways: + +- By transforming them to `require` statements. +- Using the `this.resolve` function to resolve the path. + +The `css-loader` is a good example of the first approach. It transforms dependencies to `require`s, by replacing `@import` statements with a `require` to the other stylesheet and `url(...)` with a `require` to the referenced file. + +In the case of the `less-loader`, it cannot transform each `@import` to a `require` because all `.less` files must be compiled in one pass for variables and mixin tracking. Therefore, the `less-loader` extends the less compiler with custom path resolving logic. It then takes advantage of the second approach, `this.resolve`, to resolve the dependency through webpack. + +T> If the language only accepts relative urls (e.g. `url(file)` always refers to `./file`), you can use the `~` convention to specify references to installed modules (e.g. those in `node_modules`). So, in the case of `url`, that would look something like `url('~some-library/image.jpg')`. + +### Common Code + +Avoid generating common code in every module the loader processes. Instead, create a runtime file in the loader and generate a `require` to that shared module. + +### Absolute Paths + +Don't insert absolute paths into the module code as they break hashing when the root for the project is moved. There's a [`stringifyRequest`](https://github.com/webpack/loader-utils#stringifyrequest) method in `loader-utils` which can be used to convert an absolute path to a relative one. + +### Peer Dependencies + +If the loader you're working on is a simple wrapper around another package, then you should include the package as a `peerDependency`. This approach allows the application's developer to specify the exact version in the `package.json` if desired. + +For instance, the `sass-loader` [specifies `node-sass`](https://github.com/webpack-contrib/sass-loader/blob/master/package.json) as peer dependency like so: + +```json +{ + "peerDependencies": { + "node-sass": "^4.0.0" + } +} +``` + + +## Testing + +So you've written a loader, followed the guidelines above, and have it set up to run locally. What's next? Let's go through a simple unit testing example to ensure our loader is working the way we expect. We'll be using the [Jest](https://facebook.github.io/jest/) framework to do this. We'll also install `babel-jest` and some presets that will allow us to use the `import` / `export` and `async` / `await`. Let's start by installing and saving these as a `devDependencies`: + +``` bash +npm install --save-dev jest babel-jest babel-preset-env +``` + +__.babelrc__ + +```json +{ + "presets": [[ + "env", + { + "targets": { + "node": "4" + } + } + ]] +} +``` + +Our loader will process `.txt` files and simply replace any instance of `[name]` with the `name` option given to the loader. Then it will output a valid JavaScript module containing the text as it's default export: + +__src/loader.js__ + +```js +import { getOptions } from 'loader-utils'; + +export default function loader(source) { + const options = getOptions(this); + + source = source.replace(/\[name\]/g, options.name); + + return `export default ${ JSON.stringify(source) }`; +} +``` + +We'll use this loader to process the following file: + +__test/example.txt__ + +``` text +Hey [name]! +``` + +Pay close attention to this next step as we'll be using the [Node.js API](/api/node) and [`memory-fs`](https://github.com/webpack/memory-fs) to execute webpack. This lets us avoid emitting `output` to disk and will give us access to the `stats` data which we can use to grab our transformed module: + +``` bash +npm install --save-dev webpack memory-fs +``` + +__test/compiler.js__ + +```js +import path from 'path'; +import webpack from 'webpack'; +import memoryfs from 'memory-fs'; + +export default (fixture, options = {}) => { + const compiler = webpack({ + context: __dirname, + entry: `./${fixture}`, + output: { + path: path.resolve(__dirname), + filename: 'bundle.js', + }, + module: { + rules: [{ + test: /\.txt$/, + use: { + loader: path.resolve(__dirname, '../src/loader.js'), + options: { + name: 'Alice' + } + } + }] + } + }); + + compiler.outputFileSystem = new memoryfs(); + + return new Promise((resolve, reject) => { + compiler.run((err, stats) => { + if (err || stats.hasErrors()) reject(err); + + resolve(stats); + }); + }); +}; +``` + +T> In this case, we've inlined our webpack configuration but you can also accept a configuration as a parameter to the exported function. This would allow you to test multiple setups using the same compiler module. + +And now, finally, we can write our test and add an npm script to run it: + +__test/loader.test.js__ + +```js +import compiler from './compiler.js'; + +test('Inserts name and outputs JavaScript', async () => { + const stats = await compiler('example.txt'); + const output = stats.toJson().modules[0].source; + + expect(output).toBe('export default "Hey Alice!\\n"'); +}); +``` + +__package.json__ + +```json +{ + "scripts": { + "test": "jest" + } +} +``` + +With everything in place, we can run it and see if our new loader passes the test: + +``` bash + PASS test/loader.test.js + ✓ Inserts name and outputs JavaScript (229ms) + +Test Suites: 1 passed, 1 total +Tests: 1 passed, 1 total +Snapshots: 0 total +Time: 1.853s, estimated 2s +Ran all test suites. +``` + +It worked! At this point you should be ready to start developing, testing, and deploying your own loaders. We hope that you'll share your creations with the rest of the community! + + +# Writing a Plugin + +Plugins expose the full potential of the webpack engine to third-party developers. Using staged build callbacks, developers can introduce their own behaviors into the webpack build process. Building plugins is a bit more advanced than building loaders, because you'll need to understand some of the webpack low-level internals to hook into them. Be prepared to read some source code! + +## Creating a Plugin + +A plugin for webpack consists of + +- A named JavaScript function. +- Defines `apply` method in its prototype. +- Specifies an [event hook](/api/compiler-hooks/) to tap into. +- Manipulates webpack internal instance specific data. +- Invokes webpack provided callback after functionality is complete. + +```javascript +// A JavaScript class. +class MyExampleWebpackPlugin { + // Define `apply` as its prototype method which is supplied with compiler as its argument + apply(compiler) { + // Specify the event hook to attach to + compiler.hooks.emit.tapAsync( + 'MyExampleWebpackPlugin', + (compilation, callback) => { + console.log('This is an example plugin!'); + console.log('Here’s the `compilation` object which represents a single build of assets:', compilation); + + // Manipulate the build using the plugin API provided by webpack + compilation.addModule(/* ... */); + + callback(); + } + ); + } +} +``` + +## Basic plugin architecture + +Plugins are instantiated objects with an `apply` method on their prototype. This `apply` method is called once by the webpack compiler while installing the plugin. The `apply` method is given a reference to the underlying webpack compiler, which grants access to compiler callbacks. A simple plugin is structured as follows: + +```javascript +class HelloWorldPlugin { + apply(compiler) { + compiler.hooks.done.tap('Hello World Plugin', ( + stats /* stats is passed as argument when done hook is tapped. */ + ) => { + console.log('Hello World!'); + }); + } +} + +module.exports = HelloWorldPlugin; +``` + +Then to use the plugin, include an instance in your webpack config `plugins` array: + +```javascript +// webpack.config.js +var HelloWorldPlugin = require('hello-world'); + +module.exports = { + // ... config settings here ... + plugins: [new HelloWorldPlugin({ options: true })] +}; +``` + +## Compiler and Compilation + +Among the two most important resources while developing plugins are the `compiler` and `compilation` objects. Understanding their roles is an important first step in extending the webpack engine. + +```javascript +class HelloCompilationPlugin { + apply(compiler) { + // Tap into compilation hook which gives compilation as argument to the callback function + compiler.hooks.compilation.tap('HelloCompilationPlugin', compilation => { + // Now we can tap into various hooks available through compilation + compilation.hooks.optimize.tap('HelloCompilationPlugin', () => { + console.log('Assets are being optimized.'); + }); + }); + } +} + +module.exports = HelloCompilationPlugin; +``` + +The list of hooks available on the `compiler`, `compilation`, and other important objects, see the [plugins API](/api/plugins/) docs. + +## Async event hooks + +Some plugin hooks are asynchronous. To tap into them, we can use `tap` method which will behave in synchronous manner or use one of `tapAsync` method or `tapPromise` method which are asynchronous methods. + +### tapAsync + +When we use `tapAsync` method to tap into plugins, we need to call the callback function which is supplied as the last argument to our function. + +```javascript +class HelloAsyncPlugin { + apply(compiler) { + compiler.hooks.emit.tapAsync('HelloAsyncPlugin', (compilation, callback) => { + // Do something async... + setTimeout(function() { + console.log('Done with async work...'); + callback(); + }, 1000); + }); + } +} + +module.exports = HelloAsyncPlugin; +``` + +#### tapPromise + +When we use `tapPromise` method to tap into plugins, we need to return a promise which resolves when our asynchronous task is completed. + +```javascript +class HelloAsyncPlugin { + apply(compiler) { + compiler.hooks.emit.tapPromise('HelloAsyncPlugin', compilation => { + // return a Promise that resolves when we are done... + return new Promise((resolve, reject) => { + setTimeout(function() { + console.log('Done with async work...'); + resolve(); + }, 1000); + }); + }); + } +} + +module.exports = HelloAsyncPlugin; +``` + +## Example + +Once we can latch onto the webpack compiler and each individual compilations, the possibilities become endless for what we can do with the engine itself. We can reformat existing files, create derivative files, or fabricate entirely new assets. + +Let's write a simple example plugin that generates a new build file called `filelist.md`; the contents of which will list all of the asset files in our build. This plugin might look something like this: + +```javascript +class FileListPlugin { + apply(compiler) { + // emit is asynchronous hook, tapping into it using tapAsync, you can use tapPromise/tap(synchronous) as well + compiler.hooks.emit.tapAsync('FileListPlugin', (compilation, callback) => { + // Create a header string for the generated file: + var filelist = 'In this build:\n\n'; + + // Loop through all compiled assets, + // adding a new line item for each filename. + for (var filename in compilation.assets) { + filelist += '- ' + filename + '\n'; + } + + // Insert this list into the webpack build as a new file asset: + compilation.assets['filelist.md'] = { + source: function() { + return filelist; + }, + size: function() { + return filelist.length; + } + }; + + callback(); + }); + } +} + +module.exports = FileListPlugin; +``` + +## Different Plugin Shapes + +A plugin can be classified into types based on the event hooks it taps into. Every event hook is pre-defined as synchronous or asynchronous or waterfall or parallel hook and hook is called internally using call/callAsync method. The list of hooks that are supported or can be tapped into are generally specified in this.hooks property. + +For example:- + +```javascript +this.hooks = { + shouldEmit: new SyncBailHook(['compilation']) +}; +``` + +It represents that the only hook supported is `shouldEmit` which is a hook of `SyncBailHook` type and the only parameter which will be passed to any plugin that taps into `shouldEmit` hook is `compilation`. + +Various types of hooks supported are :- + +### Synchronous Hooks + +- __SyncHook__ + + - Defined as `new SyncHook([params])` + - Tapped into using `tap` method. + - Called using `call(...params)` method. + +- __Bail Hooks__ + + - Defined using `SyncBailHook[params]` + - Tapped into using `tap` method. + - Called using `call(...params)` method. + + In these type of hooks, each of the plugin callbacks will be invoked one after the other with the specific `args`. If any value is returned except undefined by any plugin, then that value is returned by hook and no further plugin callback is invoked. Many useful events like `optimizeChunks`, `optimizeChunkModules` are SyncBailHooks. + +- __Waterfall Hooks__ + + - Defined using `SyncWaterfallHook[params]` + - Tapped into using `tap` method. + - Called using `call( ... params)` method + + Here each of the plugins are called one after the other with the arguments from the return value of the previous plugin. The plugin must take the order of its execution into account. + It must accept arguments from the previous plugin that was executed. The value for the first plugin is `init`. Hence at least 1 param must be supplied for waterfall hooks. This pattern is used in the Tapable instances which are related to the webpack templates like `ModuleTemplate`, `ChunkTemplate` etc. + +### Asynchronous Hooks + +- __Async Series Hook__ + + - Defined using `AsyncSeriesHook[params]` + - Tapped into using `tap`/`tapAsync`/`tapPromise` method. + - Called using `callAsync( ... params)` method + + The plugin handler functions are called with all arguments and a callback function with the signature `(err?: Error) -> void`. The handler functions are called in order of registration. `callback` is called after all the handlers are called. + This is also a commonly used pattern for events like `emit`, `run`. + +- __Async waterfall__ The plugins will be applied asynchronously in the waterfall manner. + + - Defined using `AsyncWaterfallHook[params]` + - Tapped into using `tap`/`tapAsync`/`tapPromise` method. + - Called using `callAsync( ... params)` method + + The plugin handler functions are called with the current value and a callback function with the signature `(err: Error, nextValue: any) -> void.` When called `nextValue` is the current value for the next handler. The current value for the first handler is `init`. After all handlers are applied, callback is called with the last value. If any handler passes a value for `err`, the callback is called with this error and no more handlers are called. + This plugin pattern is expected for events like `before-resolve` and `after-resolve`. + +- __Async Series Bail__ + + - Defined using `AsyncSeriesBailHook[params]` + - Tapped into using `tap`/`tapAsync`/`tapPromise` method. + - Called using `callAsync( ... params)` method + + someMethod() { + // Call a hook: + this.hooks.compilation.call(); + +- __Async Parallel__ + + - Defined using `AsyncParallelHook[params]` + - Tapped into using `tap`/`tapAsync`/`tapPromise` method. + - Called using `callAsync( ... params)` method + +- __Async Series Bail__ + + - Defined using `AsyncSeriesBailHook[params]` + - Tapped into using `tap`/`tapAsync`/`tapPromise` method. + - Called using `callAsync( ... params)` method + + +# Plugin Patterns + +Plugins grant unlimited opportunity to perform customizations within the webpack build system. This allows you to create custom asset types, perform unique build modifications, or even enhance the webpack runtime while using middleware. The following are some features of webpack that become useful while writing plugins. + +## Exploring assets, chunks, modules, and dependencies + +After a compilation is sealed, all structures within the compilation may be traversed. + +```javascript +class MyPlugin { + apply(compiler) { + compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => { + // Explore each chunk (build output): + compilation.chunks.forEach(chunk => { + // Explore each module within the chunk (built inputs): + chunk.modules.forEach(module => { + // Explore each source file path that was included into the module: + module.fileDependencies.forEach(filepath => { + // we've learned a lot about the source structure now... + }); + }); + + // Explore each asset filename generated by the chunk: + chunk.files.forEach(filename => { + // Get the asset source for each file generated by the chunk: + var source = compilation.assets[filename].source(); + }); + }); + + callback(); + }); + } +} +module.exports = MyPlugin; +``` + +- `compilation.modules`: An array of modules (built inputs) in the compilation. Each module manages the build of a raw file from your source library. +- `module.fileDependencies`: An array of source file paths included into a module. This includes the source JavaScript file itself (ex: `index.js`), and all dependency asset files (stylesheets, images, etc) that it has required. Reviewing dependencies is useful for seeing what source files belong to a module. +- `compilation.chunks`: An array of chunks (build outputs) in the compilation. Each chunk manages the composition of a final rendered assets. +- `chunk.modules`: An array of modules that are included into a chunk. By extension, you may look through each module's dependencies to see what raw source files fed into a chunk. +- `chunk.files`: An array of output filenames generated by the chunk. You may access these asset sources from the `compilation.assets` table. + +### Monitoring the watch graph + +While running webpack middleware, each compilation includes a `fileDependencies` array (what files are being watched) and a `fileTimestamps` hash that maps watched file paths to a timestamp. These are extremely useful for detecting what files have changed within the compilation: + +```javascript +class MyPlugin { + constructor() { + this.startTime = Date.now(); + this.prevTimestamps = {}; + } + apply(compiler) { + compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => { + var changedFiles = Object.keys(compilation.fileTimestamps).filter( + watchfile => { + return ( + (this.prevTimestamps[watchfile] || this.startTime) < + (compilation.fileTimestamps[watchfile] || Infinity) + ); + } + ); + + this.prevTimestamps = compilation.fileTimestamps; + callback(); + }); + } +} + +module.exports = MyPlugin; +``` + +You may also feed new file paths into the watch graph to receive compilation triggers when those files change. Simply push valid file paths into the `compilation.fileDependencies` array to add them to the watch. Note: the `fileDependencies` array is rebuilt in each compilation, so your plugin must push its own watched dependencies into each compilation to keep them under watch. + +## Changed chunks + +Similar to the watch graph, it's fairly simple to monitor changed chunks (or modules, for that matter) within a compilation by tracking their hashes. + +```javascript +class MyPlugin { + constructor() { + this.chunkVersions = {}; + } + apply(compiler) { + compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => { + var changedChunks = compilation.chunks.filter(chunk => { + var oldVersion = this.chunkVersions[chunk.name]; + this.chunkVersions[chunk.name] = chunk.hash; + return chunk.hash !== oldVersion; + }); + callback(); + }); + } +} + +module.exports = MyPlugin; +``` + + +# Release Process + +The release process for deploying webpack is actually quite painless. Read through the following steps, so you have a clear understanding of how it's done. + + +## Pull Requests + +When merging pull requests into the `master` branch, select the _Create Merge Commit_ option. + + +## Releasing + +```sh +npm version patch && git push --follow-tags && npm publish +npm version minor && git push --follow-tags && npm publish +npm version major && git push --follow-tags && npm publish +``` + +_This will increment the package version, commits the changes, cuts a __local tag__, push to github & publish the npm package._ + +After that go to the github [releases page](https://github.com/webpack/webpack/releases) and write a Changelog for the new tag. + + +# Debugging + +When contributing to the core repo, writing a loader/plugin, or even just working on complex project, debugging tools can be central to your workflow. Whether the problem is slow performance on a large project or an unhelpful traceback, the following utilities can make figuring it out less painful. + +- The [`stats` data](/api/stats) made available through [Node](/api/node#stats-object) and the [CLI](/api/cli#common-options). +- Chrome __DevTools__ via `node-nightly` and the latest Node.js versions. + + +## Stats + +Whether you want to sift through [this data](/api/stats) manually or use a tool to process it, the `stats` data can be extremely useful when debugging build issues. We won't go in depth here as there's an [entire page](/api/stats) dedicated to its contents, but know that you can use it to find the following information: + +- The contents of every module. +- The modules contained within every chunk. +- Per module compilation and resolving stats. +- Build errors and warnings. +- The relationships between modules. +- And much more... + +On top of that, the official [analyze tool](https://github.com/webpack/analyse) and [various others](/guides/code-splitting#bundle-analysis) will accept this data and visualize it in various ways. + + +## DevTools + +While [`console`](https://nodejs.org/api/console.html) statements may work well in simpler scenarios, sometimes a more robust solution is needed. As most front-end developers already know, Chrome DevTools are a life saver when debugging web applications, _but they don’t have to stop there_. As of Node v6.3.0+, developers can use the built-in `--inspect` flag to debug a node program in DevTools. + +This gives you the power to easily create breakpoints, debug memory usage, expose and examine objects in the console, and much more. In this short demo, we'll utilize the [`node-nightly`](https://github.com/hemanth/node-nightly) package which provides access to the latest and greatest inspecting capabilities. + +W> The `--inspect` interface has been available since v6.3.0 so feel to try it out with your local version, but be warned that certain features and flags may differ from the ones in this demo. + +Let's start by installing it globally: + +``` bash +npm install --global node-nightly +``` + +Now, we'll need to run it once to finish the installation: + +``` bash +node-nightly +``` + +Now, we can simply use `node-nightly` along with the `--inspect` flag to start our build in any webpack-based project. Note that we cannot run NPM `scripts`, e.g. `npm run build`, so we'll have specify the full `node_modules` path: + +``` bash +node-nightly --inspect ./node_modules/webpack/bin/webpack.js +``` + +Which should output something like: + +``` bash +Debugger listening on ws://127.0.0.1:9229/c624201a-250f-416e-a018-300bbec7be2c +For help see https://nodejs.org/en/docs/inspector +``` + +Now jump to `chrome://inspect` in the browser and you should see any active scripts you've inspected under the _Remote Target_ header. Click the "inspect" link under each script to open a dedicated debugger or the _Open dedicated DevTools for Node_ link for a session that will connect automatically. You can also check out the [NiM extension](https://chrome.google.com/webstore/detail/nodejs-v8-inspector-manag/gnhhdgbaldcilmgcpfddgdbkhjohddkj), a handy Chrome plugin that will automatically open a DevTools tab every time you `--inspect` a script. + +We recommend using the `--inspect-brk` flag which will break on the first statement of the script allowing you to go through the source to set breakpoints and start/stop the build as you please. Also, don't forget that you can still pass arguments to the script. For example, if you have multiple configuration files you could pass `--config webpack.prod.js` to specify the configuration you'd like to debug. diff --git a/src/content/guides/_guides_all.md b/src/content/guides/_guides_all.md new file mode 100644 index 000000000000..dab542340ea2 --- /dev/null +++ b/src/content/guides/_guides_all.md @@ -0,0 +1,4880 @@ + + +# Installation + +This guide goes through the various methods used to install webpack. + + +## Prerequisites + +Before we begin, make sure you have a fresh version of [Node.js](https://nodejs.org/en/) installed. The current Long Term Support (LTS) release is an ideal starting point. You may run into a variety of issues with the older versions as they may be missing functionality webpack and/or its related packages require. + + +## Local Installation + +The latest webpack release is: + +[![GitHub release](https://img.shields.io/npm/v/webpack.svg?label=webpack&style=flat-square&maxAge=3600)](https://github.com/webpack/webpack/releases) + +To install the latest release or a specific version, run one of the following commands: + +``` bash +npm install --save-dev webpack +npm install --save-dev webpack@ +``` + +If you're using webpack v4 or later, you'll need to install the [CLI](/api/cli/). + +``` bash +npm install --save-dev webpack-cli +``` + +Installing locally is what we recommend for most projects. This makes it easier to upgrade projects individually when breaking changes are introduced. Typically webpack is run via one or more [npm scripts](https://docs.npmjs.com/misc/scripts) which will look for a webpack installation in your local `node_modules` directory: + +```json +"scripts": { + "start": "webpack --config webpack.config.js" +} +``` + +T> To run the local installation of webpack you can access its bin version as `node_modules/.bin/webpack`. + + +## Global Installation + +The following NPM installation will make `webpack` available globally: + +``` bash +npm install --global webpack +``` + +W> Note that this is __not a recommended practice__. Installing globally locks you down to a specific version of webpack and could fail in projects that use a different version. + + +## Bleeding Edge + +If you are enthusiastic about using the latest that webpack has to offer, you can install beta versions or even directly from the webpack repository using the following commands: + +``` bash +npm install webpack@beta +npm install webpack/webpack# +``` + +W> Take caution when installing these bleeding edge releases! They may still contain bugs and therefore should not be used in production. + + +# Getting Started + +Webpack is used to compile JavaScript modules. Once [installed](/guides/installation), you can interface with webpack either from its [CLI](/api/cli) or [API](/api/node). If you're still new to webpack, please read through the [core concepts](/concepts) and [this comparison](/comparison) to learn why you might use it over the other tools that are out in the community. + +## Basic Setup + +First let's create a directory, initialize npm, [install webpack locally](/guides/installation#local-installation), and install the webpack-cli (the tool used to run webpack on the command line): + +``` bash +mkdir webpack-demo && cd webpack-demo +npm init -y +npm install webpack webpack-cli --save-dev +``` + +T> Throughout the Guides we will use `diff` blocks to show you what changes we're making to directories, files, and code. + +Now we'll create the following directory structure, files and their contents: + +__project__ + +``` diff + webpack-demo + |- package.json ++ |- index.html ++ |- /src ++ |- index.js +``` + +__src/index.js__ + +``` javascript +function component() { + let element = document.createElement('div'); + + // Lodash, currently included via a script, is required for this line to work + element.innerHTML = _.join(['Hello', 'webpack'], ' '); + + return element; +} + +document.body.appendChild(component()); +``` + +__index.html__ + +``` html + + + + Getting Started + + + + + + +``` + +We also need to adjust our `package.json` file in order to make sure we mark our package as `private`, as well as removing the `main` entry. This is to prevent an accidental publish of your code. + +T> If you want to learn more about the inner workings of `package.json`, then we recommend reading the [npm documentation](https://docs.npmjs.com/files/package.json). + +__package.json__ + +``` diff + { + "name": "webpack-demo", + "version": "1.0.0", + "description": "", ++ "private": true, +- "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "webpack": "^4.20.2", + "webpack-cli": "^3.1.2" + }, + "dependencies": {} + } +``` + +In this example, there are implicit dependencies between the ` + + +- ++ + + +``` + +In this setup, `index.js` explicitly requires `lodash` to be present, and binds it as `_` (no global scope pollution). By stating what dependencies a module needs, webpack can use this information to build a dependency graph. It then uses the graph to generate an optimized bundle where scripts will be executed in the correct order. + +With that said, let's run `npx webpack`, which will take our script at `src/index.js` as the [entry point](/concepts/entry-points), and will generate `dist/main.js` as the [output](/concepts/output). The `npx` command, which ships with Node 8.2/npm 5.2.0 or higher, runs the webpack binary (`./node_modules/.bin/webpack`) of the webpack package we installed in the beginning: + +``` bash +npx webpack + +... +Built at: 13/06/2018 11:52:07 + Asset Size Chunks Chunk Names +main.js 70.4 KiB 0 [emitted] main +... + +WARNING in configuration +The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment. +You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/ +``` + +T> Your output may vary a bit, but if the build is successful then you are good to go. Also, don't worry about the warning, we'll tackle that later. + +Open `index.html` in your browser and, if everything went right, you should see the following text: 'Hello webpack'. + + +## Modules + +The [`import`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) and [`export`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export) statements have been standardized in [ES2015](https://babeljs.io/learn-es2015/) and [are supported in most browsers](https://caniuse.com/#search=modules). Some older browsers still lag behind but webpack supports modules out of the box. + +Behind the scenes, webpack actually "transpiles" the code so that older browsers can also run it. If you inspect `dist/main.js`, you might be able to see how webpack does this, it's quite ingenious! Besides `import` and `export`, webpack supports various other module syntaxes as well, see [Module API](/api/module-methods) for more information. + +Note that webpack will not alter any code other than `import` and `export` statements. If you are using other [ES2015 features](http://es6-features.org/), make sure to [use a transpiler](/loaders/#transpiling) such as [Babel](https://babeljs.io/) or [Bublé](https://buble.surge.sh/guide/) via webpack's [loader system](/concepts/loaders/). + + +## Using a Configuration + +As of version 4, webpack doesn't require any configuration, but most projects will need a more complex setup, which is why webpack supports a [configuration file](/concepts/configuration). This is much more efficient than having to manually type in a lot of commands in the terminal, so let's create one: + +__project__ + +``` diff + webpack-demo + |- package.json ++ |- webpack.config.js + |- /dist + |- index.html + |- /src + |- index.js +``` + +__webpack.config.js__ + +``` javascript +const path = require('path'); + +module.exports = { + entry: './src/index.js', + output: { + filename: 'main.js', + path: path.resolve(__dirname, 'dist') + } +}; +``` + +Now, let's run the build again but instead using our new configuration file: + +``` bash +npx webpack --config webpack.config.js + +... + Asset Size Chunks Chunk Names +main.js 70.4 KiB 0 [emitted] main +... + +WARNING in configuration +The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment. +You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/ +``` + +T> If a `webpack.config.js` is present, the `webpack` command picks it up by default. We use the `--config` option here only to show that you can pass a config of any name. This will be useful for more complex configurations that need to be split into multiple files. + +A configuration file allows far more flexibility than simple CLI usage. We can specify loader rules, plugins, resolve options and many other enhancements this way. See the [configuration documentation](/configuration) to learn more. + + +## NPM Scripts + +Given it's not particularly fun to run a local copy of webpack from the CLI, we can set up a little shortcut. Let's adjust our _package.json_ by adding an [npm script](https://docs.npmjs.com/misc/scripts): + +__package.json__ + +``` diff + { + "name": "webpack-demo", + "version": "1.0.0", + "description": "", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", ++ "build": "webpack" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "webpack": "^4.20.2", + "webpack-cli": "^3.1.2" + }, + "dependencies": { + "lodash": "^4.17.5" + } + } +``` + +Now the `npm run build` command can be used in place of the `npx` command we used earlier. Note that within `scripts` we can reference locally installed npm packages by name the same way we did with `npx`. This convention is the standard in most npm-based projects because it allows all contributors to use the same set of common scripts (each with flags like `--config` if necessary). + +Now run the following command and see if your script alias works: + +``` bash +npm run build + +... + Asset Size Chunks Chunk Names +main.js 70.4 KiB 0 [emitted] main +... + +WARNING in configuration +The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment. +You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/. +``` + +T> Custom parameters can be passed to webpack by adding two dashes between the `npm run build` command and your parameters, e.g. `npm run build -- --colors`. + + +## Conclusion + +Now that you have a basic build together you should move on to the next guide [`Asset Management`](/guides/asset-management) to learn how to manage assets like images and fonts with webpack. At this point, your project should look like this: + +__project__ + +``` diff +webpack-demo +|- package.json +|- webpack.config.js +|- /dist + |- main.js + |- index.html +|- /src + |- index.js +|- /node_modules +``` + +T> If you're using npm 5, you'll probably also see a `package-lock.json` file in your directory. + +If you want to learn more about webpack's design, you can check out the [basic concepts](/concepts) and [configuration](/configuration) pages. Furthermore, the [API](/api) section digs into the various interfaces webpack offers. + + +# Asset Management + +If you've been following the guides from the start, you will now have a small project that shows "Hello webpack". Now let's try to incorporate some other assets, like images, to see how they can be handled. + +Prior to webpack, front-end developers would use tools like grunt and gulp to process these assets and move them from their `/src` folder into their `/dist` or `/build` directory. The same idea was used for JavaScript modules, but tools like webpack will __dynamically bundle__ all dependencies (creating what's known as a [dependency graph](/concepts/dependency-graph)). This is great because every module now _explicitly states its dependencies_ and we'll avoid bundling modules that aren't in use. + +One of the coolest webpack features is that you can also _include any other type of file_, besides JavaScript, for which there is a loader. This means that the same benefits listed above for JavaScript (e.g. explicit dependencies) can be applied to everything used in building a website or web app. Let's start with CSS, as you may already be familiar with that setup. + +## Setup + +Let's make a minor change to our project before we get started: + +__dist/index.html__ + +``` diff + + + +- Getting Started ++ Asset Management + + +- ++ + + +``` + +__webpack.config.js__ + +``` diff + const path = require('path'); + + module.exports = { + entry: './src/index.js', + output: { +- filename: 'main.js', ++ filename: 'bundle.js', + path: path.resolve(__dirname, 'dist') + } + }; +``` + + +## Loading CSS + +In order to `import` a CSS file from within a JavaScript module, you need to install and add the [style-loader](/loaders/style-loader) and [css-loader](/loaders/css-loader) to your [`module` configuration](/configuration/module): + +``` bash +npm install --save-dev style-loader css-loader +``` + +__webpack.config.js__ + +``` diff + const path = require('path'); + + module.exports = { + entry: './src/index.js', + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, 'dist') + }, ++ module: { ++ rules: [ ++ { ++ test: /\.css$/, ++ use: [ ++         'style-loader', ++         'css-loader' ++       ] ++ } ++ ] ++ } + }; +``` + +T> webpack uses a regular expression to determine which files it should look for and serve to a specific loader. In this case any file that ends with `.css` will be served to the `style-loader` and the `css-loader`. + +This enables you to `import './style.css'` into the file that depends on that styling. Now, when that module is run, a `