diff --git a/.alexrc b/.alexrc index 206e6efd2d39..b8f06d37fd66 100644 --- a/.alexrc +++ b/.alexrc @@ -1,3 +1,22 @@ { - "allow": ["boogeyman-boogeywoman"] + "allow": [ + "bigger", + "color", + "lies", + "execute", + "executed", + "execution", + "host-hostess", + "disabled", + "crash", + "failure", + "period", + "hook", + "dirty", + "host-hostess", + "fire", + "remains", + "jade", + "failed" + ] } \ No newline at end of file diff --git a/.editorconfig b/.editorconfig index edeb3a492d16..ef11db305ed6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,12 +5,16 @@ root = true [*.{js}] charset = utf-8 +[*] +trim_trailing_whitespace = true +insert_final_newline = true + # 4 space indentation [*.{md,js,jsx,scss,hbs}] indent_style = space indent_size = 2 # Format Config -[{package.json}] +[{package.json,.alexrc,babelrc,.eslintignore,.eslintrc,.markdownlint.json,.proselintrc}] indent_style = space indent_size = 2 diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTING.md rename to .github/CONTRIBUTING.md diff --git a/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md similarity index 100% rename from ISSUE_TEMPLATE.md rename to .github/ISSUE_TEMPLATE.md diff --git a/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from PULL_REQUEST_TEMPLATE.md rename to .github/PULL_REQUEST_TEMPLATE.md diff --git a/.markdownlintrc b/.markdownlint.json similarity index 80% rename from .markdownlintrc rename to .markdownlint.json index 4d3437ad3a61..e1cdc44d6a46 100644 --- a/.markdownlintrc +++ b/.markdownlint.json @@ -2,7 +2,8 @@ "default": true, "MD002": false, "MD007": { "indent": 4 }, - "MD013": { "line_length": 500 }, + "MD013": { "line_length": 600 }, + "MD026": false, "MD029": { "style": "ordered"}, "MD033": false, "MD034": false, diff --git a/.proselintrc b/.proselintrc index 0cce7fb60c09..da5719979474 100644 --- a/.proselintrc +++ b/.proselintrc @@ -1,84 +1,84 @@ { - "max_errors": 1000, - "checks": { - "phrasal_adjectives.ly" : false, - "preferred_forms" : false, - "airlinese.misc" : true, - "annotations.misc" : false, - "archaism.misc" : true, - "cliches.hell" : true, - "cliches.misc" : true, - "consistency.spacing" : true, - "consistency.spelling" : true, - "corporate_speak.misc" : true, - "cursing.filth" : true, - "cursing.nfl" : false, - "cursing.nword" : true, - "dates_times.am_pm" : true, - "dates_times.dates" : true, - "hedging.misc" : true, - "hyperbole.misc" : false, - "jargon.misc" : true, - "lexical_illusions.misc" : true, - "links.broken" : false, - "malapropisms.misc" : true, - "misc.apologizing" : true, - "misc.back_formations" : true, - "misc.bureaucratese" : true, - "misc.but" : false, - "misc.capitalization" : true, - "misc.chatspeak" : true, - "misc.commercialese" : true, - "misc.composition" : true, - "misc.currency" : true, - "misc.debased" : true, - "misc.false_plurals" : true, - "misc.illogic" : true, - "misc.inferior_superior" : true, - "misc.latin" : true, - "misc.many_a" : true, - "misc.metaconcepts" : true, - "misc.metadiscourse" : true, - "misc.narcissism" : true, - "misc.not_guilty" : true, - "misc.phrasal_adjectives" : false, - "misc.preferred_forms" : false, - "misc.pretension" : true, - "misc.professions" : true, - "misc.punctuation" : true, - "misc.scare_quotes" : true, - "misc.suddenly" : true, - "misc.tense_present" : true, - "misc.waxed" : true, - "misc.whence" : true, - "mixed_metaphors.misc" : true, - "mondegreens.misc" : true, - "needless_variants.misc" : true, - "nonwords.misc" : true, - "oxymorons.misc" : true, - "psychology.misc" : true, - "redundancy.misc" : true, - "redundancy.ras_syndrome" : true, - "skunked_terms.misc" : true, - "spelling.able_atable" : true, - "spelling.able_ible" : true, - "spelling.athletes" : true, - "spelling.em_im_en_in" : true, - "spelling.er_or" : true, - "spelling.in_un" : true, - "spelling.misc" : true, - "security.credit_card" : true, - "security.password" : true, - "sexism.misc" : true, - "terms.animal_adjectives" : true, - "terms.denizen_labels" : true, - "terms.eponymous_adjectives" : true, - "terms.venery" : true, - "typography.diacritical_marks" : true, - "typography.exclamation" : false, - "typography.symbols" : false, - "uncomparables.misc" : true, - "weasel_words.misc" : true, - "weasel_words.very" : true - } + "max_errors": 1000, + "checks": { + "phrasal_adjectives.ly" : false, + "preferred_forms" : false, + "airlinese.misc" : true, + "annotations.misc" : false, + "archaism.misc" : true, + "cliches.hell" : true, + "cliches.misc" : true, + "consistency.spacing" : true, + "consistency.spelling" : true, + "corporate_speak.misc" : true, + "cursing.filth" : true, + "cursing.nfl" : false, + "cursing.nword" : true, + "dates_times.am_pm" : true, + "dates_times.dates" : true, + "hedging.misc" : true, + "hyperbole.misc" : false, + "jargon.misc" : true, + "lexical_illusions.misc" : true, + "links.broken" : false, + "malapropisms.misc" : true, + "misc.apologizing" : true, + "misc.back_formations" : true, + "misc.bureaucratese" : true, + "misc.but" : false, + "misc.capitalization" : true, + "misc.chatspeak" : true, + "misc.commercialese" : true, + "misc.composition" : true, + "misc.currency" : true, + "misc.debased" : true, + "misc.false_plurals" : true, + "misc.illogic" : true, + "misc.inferior_superior" : true, + "misc.latin" : true, + "misc.many_a" : true, + "misc.metaconcepts" : true, + "misc.metadiscourse" : true, + "misc.narcissism" : true, + "misc.not_guilty" : true, + "misc.phrasal_adjectives" : false, + "misc.preferred_forms" : false, + "misc.pretension" : true, + "misc.professions" : true, + "misc.punctuation" : true, + "misc.scare_quotes" : true, + "misc.suddenly" : true, + "misc.tense_present" : true, + "misc.waxed" : true, + "misc.whence" : true, + "mixed_metaphors.misc" : true, + "mondegreens.misc" : true, + "needless_variants.misc" : true, + "nonwords.misc" : true, + "oxymorons.misc" : true, + "psychology.misc" : true, + "redundancy.misc" : true, + "redundancy.ras_syndrome" : true, + "skunked_terms.misc" : true, + "spelling.able_atable" : true, + "spelling.able_ible" : true, + "spelling.athletes" : true, + "spelling.em_im_en_in" : true, + "spelling.er_or" : true, + "spelling.in_un" : true, + "spelling.misc" : true, + "security.credit_card" : true, + "security.password" : true, + "sexism.misc" : true, + "terms.animal_adjectives" : true, + "terms.denizen_labels" : true, + "terms.eponymous_adjectives" : true, + "terms.venery" : true, + "typography.diacritical_marks" : true, + "typography.exclamation" : false, + "typography.symbols" : false, + "uncomparables.misc" : true, + "weasel_words.misc" : true, + "weasel_words.very" : true + } } diff --git a/.travis.yml b/.travis.yml index d997448f5df1..06ad990738bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,6 @@ script: - bash ./scripts/deploy.sh sudo: required install: - - npm i yarn -g + - npm install --global yarn - yarn - sudo pip install proselint diff --git a/README.md b/README.md index b1c9c151b699..7b4e95a2ccb4 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,10 @@ For more information see the [contributors page](https://github.com/webpack/webp Check out the [MVP Milestone](https://github.com/webpack/webpack.js.org/milestones) for the current status. +## Translation + +If you hope to localize this documentation please transit to [translate branch](https://github.com/webpack/webpack.js.org/tree/translation). + ## License The content is available under [Creative Commons BY 4.0](https://creativecommons.org/licenses/by/4.0/) license. diff --git a/components/sidebar-item/sidebar-item-style.scss b/components/sidebar-item/sidebar-item-style.scss index c2149dd8ee66..1fb1d219d4e9 100644 --- a/components/sidebar-item/sidebar-item-style.scss +++ b/components/sidebar-item/sidebar-item-style.scss @@ -83,4 +83,10 @@ transform: rotate(90deg); } } + + &--disabled { + .sidebar-item__toggle { + color: #AAA; + } + } } diff --git a/components/sidebar-item/sidebar-item.jsx b/components/sidebar-item/sidebar-item.jsx index acaacf2dc5f2..c38fc4c58830 100644 --- a/components/sidebar-item/sidebar-item.jsx +++ b/components/sidebar-item/sidebar-item.jsx @@ -16,14 +16,17 @@ export default class SidebarItem extends React.Component { render() { let { title, anchors = [] } = this.props; let openMod = this.state.open ? `${block}--open` : ''; + let disabledMod = anchors.length == 0 ? `${block}--disabled` : ''; return ( -
+
{ anchors.length > 0 ? ( - ) : null } + ) : + } The new CLI for webpack is under development. New features are being added such as the `--init` flag. [Check it out!](https://github.com/webpack/webpack-cli) + ## 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 [] ``` @@ -77,6 +81,7 @@ This will form the bundle with both the files as separate entry points. [1] ./src/others.js 29 bytes {0} {1} [built] ``` + ### Common Options **List all of the options available on the cli** @@ -115,13 +120,15 @@ In every other case, webpack prints out a set of stats showing bundle, chunk and This response is accepted by webpack's [analyse tool](https://webpack.github.com/analyse), or chrisbateman's [webpack-visualizer](https://chrisbateman.github.io/webpack-visualizer/), or th0r's [webpack-bundle-analyzer](https://github.com/th0r/webpack-bundle-analyzer). The analyse tool will take in the JSON and provide all the details of the build in graphical form. -*Further reads:* +*Further reading:* + * [Analyzing Build Statistics](https://survivejs.com/webpack/optimizing-build/analyzing-build-statistics/) * [Three simple ways to inspect a webpack bundle](https://medium.com/@joeclever/three-simple-ways-to-inspect-a-webpack-bundle-7f6a8fe7195d#.7d2i06mjx) * [Optimising your application bundle size with webpack](https://hackernoon.com/optimising-your-application-bundle-size-with-webpack-e85b00bab579#.5w5ko08pq) * [Analyzing & optimizing your webpack bundle](https://medium.com/@ahmedelgabri/analyzing-optimizing-your-webpack-bundle-8590818af4df#.hce4vdjs9) * [Analysing and minimising the size of client side bundle with webpack and source-map-explorer](https://medium.com/@nimgrg/analysing-and-minimising-the-size-of-client-side-bundle-with-webpack-and-source-map-explorer-41096559beca#.c3t2srr8x) + ### Output Options This set of options allows you to manipulate certain [output](/configuration/output) parameters of your build. @@ -138,6 +145,7 @@ This set of options allows you to manipulate certain [output](/configuration/out | --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 | + #### Example Usage ```bash @@ -166,6 +174,7 @@ webpack.js index=./src/index.js index2=./src/index2.js --output-path='./dist' -- [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 @@ -176,6 +185,7 @@ This set of options allows you to better debug the application containing assets | --devtool | Define [source map type](/configuration/devtool/) for the bundled resources | string | - | | --progress | Print compilation progress in percentage | boolean | false | + ### Module Options These options allow you to bind [modules](/configuration/module/) as allowed by webpack @@ -186,6 +196,7 @@ These options allow you to bind [modules](/configuration/module/) as allowed by | --module-bind-post | Bind an extension to a post loader | | | --module-bind-pre | Bind an 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. @@ -198,6 +209,7 @@ These options makes the build [watch](/configuration/watch/) for changes in file | --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 @@ -208,6 +220,7 @@ These options allow you to manipulate optimisations for a production build using | --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 | [UglifyJsPlugin](/plugins/uglifyjs-webpack-plugin/) & [LoaderOptionsPlugin](/plugins/loader-options-plugin/) | + ### Resolve Options These allow you to configure the webpack [resolver](/configuration/resolve/) with aliases and extensions. @@ -218,6 +231,7 @@ These allow you to configure the webpack [resolver](/configuration/resolve/) wit | --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. @@ -241,6 +255,7 @@ These options allow webpack to display various [stats](/configuration/stats/) an | --sort-modules-by | Sorts the modules list by property in module | string | | --verbose | Show more details | boolean | + ### Advanced Options | Parameter | Explanation | Usage | @@ -265,6 +280,7 @@ These options allow webpack to display various [stats](/configuration/stats/) an | -d | --debug --devtool eval-cheap-module-source-map --output-pathinfo | | -p | --optimize-minimize --define process.env.NODE_ENV="production", see [building for production](/guides/production-build) | + ### Profiling This option profiles the compilation and includes this information in the stats output. It 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. diff --git a/content/api/loaders.md b/content/api/loaders.md index fec18f9e9709..3b54086c1c52 100644 --- a/content/api/loaders.md +++ b/content/api/loaders.md @@ -11,10 +11,13 @@ Loaders are transformations that are applied on the source code of a module. The ## How to write a loader -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 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 ### Sync Loader @@ -36,6 +39,7 @@ module.exports = function(content) { }; ``` + ### Async Loader **async-loader.js** @@ -64,6 +68,7 @@ module.exports = function(content) { 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. @@ -80,6 +85,7 @@ module.exports = function(content) { module.exports.raw = true; ``` + ### Pitching Loader Loaders are **always** called from right to left. But, in some cases, loaders do not care about the results of the previous loader or the resource. They only care for **metadata**. The `pitch` method on the loaders is called from **left to right** before the loaders are called (from right to left). @@ -99,6 +105,7 @@ module.exports.pitch = function(remainingRequest, precedingRequest, data) { }; ``` + ## The loader context The loader context represents the properties that are available inside of a loader assigned to the `this` property. @@ -110,22 +117,26 @@ In `/abc/file.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.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. In case the loader was configured with an [`options`](/configuration/module/#useentry) object, this will be a reference to the object. @@ -133,6 +144,7 @@ In the example: `"/abc/loader1.js?xyz!/abc/node_modules/loader2/index.js!/abc/re T> Use the [`getOptions` method from the `loader-utils`](https://github.com/webpack/loader-utils#getoptions) to extract the given loader options. + ### `this.callback` A function that can be called synchronously or asynchronously in order to return multiple results. The expected arguments are: @@ -153,14 +165,17 @@ this.callback( In case this function is called, you should return undefined to avoid ambigious 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: @@ -173,6 +188,7 @@ By default, loader results are flagged as cacheable. Call this method passing `f 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. @@ -198,46 +214,54 @@ In the example: ] ``` + ### `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 @@ -246,6 +270,7 @@ emitWarning(message: string) Emit a warning. + ### `this.emitError` ```typescript @@ -254,6 +279,7 @@ emitError(message: string) Emit an error. + ### `this.loadModule` ```typescript @@ -262,6 +288,7 @@ 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 @@ -270,6 +297,7 @@ resolve(context: string, request: string, callback: function(err, result: string Resolve a request like a require expression. + ### `this.addDependency` ```typescript @@ -279,6 +307,7 @@ 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/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 @@ -287,6 +316,7 @@ addContextDependency(directory: string) Add a directory as dependency of the loader result. + ### `this.clearDependencies` ```typescript @@ -295,6 +325,7 @@ clearDependencies() Remove all dependencies of the loader result. Even initial dependencies and these of other loaders. Consider using `pitch`. + ### `this.emitFile` ```typescript @@ -303,14 +334,17 @@ 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 planing to remove them from the context. They are still listed here for documentation purposes. + ### `this.exec` ```typescript @@ -319,6 +353,7 @@ exec(code: string, filename: string) Execute some code fragment like a module. + ### `this.resolveSync` ```typescript @@ -327,34 +362,42 @@ 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` The options passed to the Compiler. + ### `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. diff --git a/content/api/node.md b/content/api/node.md index 442722caa55d..84860556f375 100644 --- a/content/api/node.md +++ b/content/api/node.md @@ -10,12 +10,13 @@ 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: -``` -npm install webpack --save-dev +``` bash +npm install --save-dev webpack ``` Then require the webpack module in your Node.js script: @@ -27,6 +28,7 @@ const webpack = require("webpack"); 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: @@ -57,8 +59,10 @@ webpack([ // ... }); ``` + T> webpack will **not** run the multiple configurations in parallel. Each configuration is only processed after the previous one has finished processing. To have webpack process them in parallel, you can use a third-party solution like [parallel-webpack](https://www.npmjs.com/package/parallel-webpack). + ## 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/) Api. The `Compiler` instance provides the following methods: @@ -66,6 +70,7 @@ If you don’t pass the `webpack` runner function a callback, it will return a w * `.run(callback)` * `.watch(watchOptions, handler)` + ## Run Calling the `run` method on the `Compiler` instance is much like the quick run method mentioned above: @@ -82,6 +87,7 @@ 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`. @@ -110,6 +116,7 @@ const watching = compiler.watch({ `Watching` options are [covered in detail here](/configuration/watch/#watchoptions). + ### Close `Watching` The `watch` method returns a `Watching` instance that exposes `.close(callback)` method. Calling this method will end watching: @@ -122,6 +129,7 @@ watching.close(() => { T> It’s not allowed to watch or run again before the existing watcher has been closed or invalidated. + ### Invalidate `Watching` Manually invalidate the current compiling round, but don’t stop watching. @@ -136,23 +144,26 @@ watching.invalidate(() => { 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 -- etc. +* Errors and Warnings (if any) +* Timings +* Module and Chunk information +* and much more... The [webpack CLI](/api/cli) uses this information to display a nicely formatted output in your console. This object exposes these 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: @@ -160,6 +171,7 @@ Returns compilation information as a JSON object. `options` can be either a stri ``` js-with-links stats.toJson("minimal"); // [more options: "verbose", etc](/configuration/stats). ``` + ``` js stats.toJson({ assets: false, @@ -171,6 +183,7 @@ All available options and presets are described in [Stats documentation](/config > Here’s [an example of this function’s output](https://github.com/webpack/analyse/blob/master/app/pages/upload/example.json) + ### `stats.toString(options)` Returns a formatted string of the compilation information (similar to [CLI](/api/cli) output). @@ -205,13 +218,14 @@ 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 +* Fatal webpack errors (wrong configuration, etc) +* Compilation errors (missing modules, syntax errors, etc) +* Compilation warnings Here’s an example that does all that: @@ -243,6 +257,7 @@ webpack({ }); ``` + ## Compiling to Memory webpack writes the output to the specified files on disk. If you want webpack to output them to a different kind of file system (memory, webDAV, etc), you can set the `outputFileSystem` option on the compiler: diff --git a/content/api/plugins/compilation.md b/content/api/plugins/compilation.md index 3a45a2b637cc..90632185d588 100644 --- a/content/api/plugins/compilation.md +++ b/content/api/plugins/compilation.md @@ -150,6 +150,27 @@ Create additional assets for the chunks. Store info about the compilation to the records +## `additional-assets` async + +Create additional assets for the compilation + +Here's an example that downloads an image. + +```javascript +compiler.plugin('compilation', function(compilation) { + compilation.plugin('additional-assets', function(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')); + } + }) + }); +}); +``` + ## `optimize-chunk-assets(chunks: Chunk[])` async Optimize the assets for the chunks. diff --git a/content/api/plugins/compiler.md b/content/api/plugins/compiler.md index dc272b0e6c68..701d4cb86e0a 100644 --- a/content/api/plugins/compiler.md +++ b/content/api/plugins/compiler.md @@ -51,7 +51,7 @@ Most user facing plugins are first registered on the `Compiler`. The working of a Compiler can be condensed into the following highlights - Usually there is one master instance of Compiler. Child compilers can be created for delegating specific tasks. - A lot of the complexity in creating a compiler goes into populating all the relevant options for it. - - `webpack` has [`WebpackOptionsDefaulter`](https://github.com/webpack/webpack/blob/master/lib/WebpackOptionsDefaulter.js) and [`WebpackOptionsApply`](https://github.com/webpack/webpack/blob/master/lib/WebpackOptionsApply.js) specifically designed to provide the `Compiler` with all the intial data it requires. + - `webpack` has [`WebpackOptionsDefaulter`](https://github.com/webpack/webpack/blob/master/lib/WebpackOptionsDefaulter.js) and [`WebpackOptionsApply`](https://github.com/webpack/webpack/blob/master/lib/WebpackOptionsApply.js) specifically designed to provide the `Compiler` with all the initial data it requires. - The `Compiler` is ultimately just a function which performs bare minimum functionality to keep a lifecycle running. It delegates all the loading/bundling/writing work to various plugins. - `new LogPlugin(args).apply(compiler)` registers the plugin to any particular hook event in the `Compiler`'s lifecycle. - The `Compiler` exposes a `run` method which kickstarts all compilation work for `webpack`. When that is done, it should call the passed in `callback` function. All the tail end work of logging stats and errors are done in this callback function. @@ -110,7 +110,7 @@ This a reference guide to all the event hooks exposed by the `Compiler`. | __`emit`__ | Before writing emitted assets to output dir | `compilation` | async | | __`after-emit`__ | After writing emitted assets to output dir | `compilation` | async | | __`done`__ | Completion of compile | `stats` | sync | -| __`fail`__ | Failure of compile | `error` | sync | +| __`failed`__ | Failure of compile | `error` | sync | | __`invalid`__ | After invalidating a watch compile | `fileName`, `changeTime` | sync | ## Examples diff --git a/content/concepts/entry-points.md b/content/concepts/entry-points.md index 209b06674dc4..85fcad04179b 100644 --- a/content/concepts/entry-points.md +++ b/content/concepts/entry-points.md @@ -8,6 +8,7 @@ contributors: Like we mentioned in the [introduction](/guides/get-started/#using-webpack-with-a-config), 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` @@ -36,6 +37,7 @@ T> **What happens when you pass an array to `entry`?** Passing an array of file This is a great choice when you are looking to quickly setup a webpack configuration for an application or tool with one entry point (IE: 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}` @@ -55,11 +57,13 @@ The object syntax is more verbose. However, this is the most scalable way of def 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 + +### Separate App and Vendor Entries **webpack.config.js** @@ -78,7 +82,8 @@ const config = { ?> Consider removing this scenario in favor of the DllPlugin, which provides a better vendor-splitting. -#### Multi Page Application + +### Multi Page Application **webpack.config.js** diff --git a/content/concepts/hot-module-replacement.md b/content/concepts/hot-module-replacement.md index ff0837c193c4..2d14fc7c0f07 100644 --- a/content/concepts/hot-module-replacement.md +++ b/content/concepts/hot-module-replacement.md @@ -13,19 +13,20 @@ Hot Module Replacement (HMR) exchanges, adds, or removes page reload. This allows you to speed up development time by updating individual modules when they are changed without refreshing the page. -## How Does It Work? + +## How It Works ### From The App View 1. The app code asks the HMR runtime to check for updates. -2. The HMR runtime downloads the updates (asynchronously) and tells the app -code that an update is available. +2. The HMR runtime downloads the updates (asynchronously) and tells the app code that an update is available. 3. The app code then asks the HMR runtime to apply the updates. 4. The HMR runtime applies the update (synchronously). You can set up HMR so that this process happens automatically, or you can choose to require user interaction for updates to occur. + ### From The Compiler (webpack) View In addition to the normal assets, the compiler needs to emit an "update" @@ -45,6 +46,7 @@ between these builds. It typically stores these IDs in memory (for example, when using [webpack-dev-server](/configuration/dev-server/)), but it's also possible to store them in a JSON file. + ### From The Module View HMR is an opt-in feature that only affects modules containing HMR code. One example @@ -59,6 +61,7 @@ means that a single handler can handle an update to a complete module tree. If a module in this tree is updated, the complete module tree is reloaded (only reloaded, not transferred). + ### From The HMR Runtime View (Technical) For the module system runtime, additional code is emitted to track module `parents` and `children`. @@ -82,7 +85,8 @@ Afterwards, all invalid modules are disposed (via the dispose handler) and unloa 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. -## What can I do with it? + +## What It Can Be Used For You can use it in development as a LiveReload replacement. [webpack-dev-server](/configuration/dev-server/) supports a diff --git a/content/concepts/loaders.md b/content/concepts/loaders.md index c1c09f3a08ff..b0e9c3b9699e 100644 --- a/content/concepts/loaders.md +++ b/content/concepts/loaders.md @@ -17,7 +17,7 @@ Loaders are transformations that are applied on the source code of a module. The For example, you can use loaders to tell webpack to load a CSS file or to convert TypeScript to JavaScript. Firstly, install the corresponding loaders: -``` +``` bash npm install --save-dev css-loader npm install --save-dev ts-loader ``` diff --git a/content/concepts/module-resolution.md b/content/concepts/module-resolution.md index 496f8c166cb8..e36e1d5b6daf 100644 --- a/content/concepts/module-resolution.md +++ b/content/concepts/module-resolution.md @@ -19,10 +19,12 @@ The dependency module can be from the application code or a third party library. webpack finds 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 @@ -33,6 +35,7 @@ import "C:\\Users\\me\\file"; Since we already have the absolute path to the file, no further resolution is required. + ### Relative paths ```js @@ -42,6 +45,7 @@ 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 @@ -53,23 +57,27 @@ Modules are searched for inside all directories specified in [`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. -Look at [Resolve API](/configuration/resolve) to know more on the configuration options mentioned above. +See [Resolve API](/configuration/resolve) to learn more on the configuration options mentioned above. diff --git a/content/concepts/output.md b/content/concepts/output.md index 18c72d3e5a67..2c82a12521d4 100644 --- a/content/concepts/output.md +++ b/content/concepts/output.md @@ -56,7 +56,7 @@ Possible values are: `"anonymous"` - Cross-origin loading is enabled. When using `anonymous` no credentials will be sent with the request. -`"use-credentials"` - Cross-origin loading is enabled and credentials will be send with the request. +`"use-credentials"` - Cross-origin loading is enabled and credentials will be sent with the request. For more information on cross-origin loading see [MDN](https://developer.mozilla.org/en/docs/Web/HTML/Element/script#attr-crossorigin) diff --git a/content/concepts/plugins.md b/content/concepts/plugins.md index 4ab5a3fd492e..2e726d7f06c2 100644 --- a/content/concepts/plugins.md +++ b/content/concepts/plugins.md @@ -12,6 +12,7 @@ contributors: 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) property. This `apply` property is called by the webpack compiler, giving access to the **entire** compilation lifecycle. @@ -34,12 +35,14 @@ ConsoleLogOnBuildWebpackPlugin.prototype.apply = function(compiler) { T> As a clever JavaScript developer you may remember the `Function.prototype.apply` method. Because of this method you can pass any function as plugin (`this` will point to the `compiler`). You can use this style to inline custom plugins in your configuration. + ## 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** @@ -72,6 +75,7 @@ const config = { module.exports = config; ``` + ### Node API ?> Even when using the Node API, users should pass plugins via the `plugins` property in the configuration. Using `compiler.apply` should not be the recommended way. diff --git a/content/configuration/configuration-types.md b/content/configuration/configuration-types.md index dd11133e7c03..0f18ad472e40 100644 --- a/content/configuration/configuration-types.md +++ b/content/configuration/configuration-types.md @@ -10,6 +10,7 @@ contributors: Besides exporting a single config object, there are a few more ways that cover other needs as well. + ## Exporting a function to use `--env` Eventually you will find the need to disambiguate in your `webpack.config.js` between [development](/guides/development) and [production builds](/guides/production-build). You have (at least) two options: @@ -29,6 +30,7 @@ Instead of exporting a configuration object, you may return a function which acc }; ``` + ## 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. @@ -46,7 +48,9 @@ module.exports = () => { } ``` + ## Exporting multiple configurations + Instead of exporting a single configuration object/function, you may export multiple configurations. 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 diff --git a/content/configuration/dev-server.md b/content/configuration/dev-server.md index 9226a0f8996c..f292dc7f8b8c 100644 --- a/content/configuration/dev-server.md +++ b/content/configuration/dev-server.md @@ -14,6 +14,7 @@ This page describes the options that affect the behavior of webpack-dev-server ( T> Options that are compatible with [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware) have 🔑 next to them. + ## `devServer` `object` @@ -42,6 +43,7 @@ If you're using dev-server through the Node.js API, the options in `devServer` w W> Be aware that when [exporting multiple configurations](/configuration/configuration-types/#exporting-multiple-configurations) only the `devServer` options for the first configuration will be taken into account and used for all the configurations in the array. + ## `devServer.clientLogLevel` `string` @@ -416,7 +418,7 @@ quiet: true Here you can access the Express app object and add your own custom middleware to it. For example, to define custom handlers for some paths: - + ```js setup(app){ app.get('/some/path', function(req, res) { diff --git a/content/configuration/entry-context.md b/content/configuration/entry-context.md index c7785f30d137..5ce627ff9893 100644 --- a/content/configuration/entry-context.md +++ b/content/configuration/entry-context.md @@ -9,6 +9,7 @@ contributors: 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` @@ -23,6 +24,7 @@ By default the current directory is used, but it's recommended to pass a value i --- + ## `entry` `string | [string] | object { : string | [string] } | (function: () => string | [string] | object { : string | [string] })` @@ -41,9 +43,12 @@ entry: { } ``` + ### 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 entrypoint for the chunk. + ### Dynamic entry ```js diff --git a/content/configuration/externals.md b/content/configuration/externals.md index 2777f648fd0c..7c202f1c9346 100644 --- a/content/configuration/externals.md +++ b/content/configuration/externals.md @@ -48,10 +48,10 @@ $('.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: - * __global__ - An external library can be available as a global variable. The consumer can achieve this by including the external library in a script tag. This is the default setting for externals. - * __commonjs__ - The consumer application may be using a CommonJS module system and hence the external library should be available as a CommonJS module. - * __commonjs2__ - Similar to the above line but where the export is `module.exports.default`. - * __amd__ - Similar to the above line but using AMD module system. +* __global__ - An external library can be available as a global variable. The consumer can achieve this by including the external library in a script tag. This is the default setting for externals. +* __commonjs__ - The consumer application may be using a CommonJS module system and hence the external library should be available as a CommonJS module. +* __commonjs2__ - Similar to the above line but where the export is `module.exports.default`. +* __amd__ - Similar to the above line but using AMD module system. `externals` accepts various syntax and interprets them in different manners. diff --git a/content/configuration/module.md b/content/configuration/module.md index e9583678fede..40a3bf2c49b1 100644 --- a/content/configuration/module.md +++ b/content/configuration/module.md @@ -10,6 +10,7 @@ contributors: These options determine how the [different types of modules](/concepts/modules) within a project will be treated. + ## `module.noParse` `RegExp | [RegExp]` @@ -20,6 +21,7 @@ Prevent webpack from parsing any files matching the given regular expression(s). noParse: /jquery|lodash/ ``` + ## `module.rules` `array` @@ -31,6 +33,7 @@ An array of [Rules](#rule) which are matched to requests when modules are create A Rule can be separated into three parts — Conditions, Results and nested Rules. + ### Rule conditions There are two input values for the conditions: @@ -47,6 +50,7 @@ When using multiple conditions, all conditions must match. W> Be careful! The resource is the _resolved_ path of the file, which means symlinked resources are the real path _not_ the symlink location. This is good to remember when using tools that symlink packages (like `npm link`), common conditions like `/node_modules/` may inadvertently miss symlinked files. + ### Rule results Rule results are used only when the Rule condition matches. @@ -54,7 +58,6 @@ Rule results are used only when the Rule condition matches. There are two output values of a Rule: 1. Applied loaders: An array of loaders applied to the resource. - 2. Parser options: An options object which should be used to create the parser for this module. These properties affect the loaders: [`loader`](#rule-loader), [`options`](#rule-options-rule-query), [`use`](#rule-use). @@ -72,6 +75,7 @@ Nested rules can be specified under the properties [`rules`](#rule-rules) and [` These rules are evaluated when the Rule condition matches. + ## `Rule.enforce` Possible values: `"pre" | "post"` @@ -159,14 +163,17 @@ parser: { A [`Condition`](#condition) matched with the resource. See details in [`Rule` conditions](#rule-conditions). + ## `Rule.resourceQuery` A [`Condition`](#condition) matched with the resource query. The condition matches against a string that starts with a question mark (`"?exampleQuery"`). See details in [`Rule` conditions](#rule-conditions). + ## `Rule.rules` An array of [`Rules`](#rule) that is also used when the Rule matches. + ## `Rule.test` `Rule.test` is a shortcut to `Rule.resource.test`. See [`Rule.resource`](#rule-resource) and [`Condition.test`](#condition) for details. @@ -259,7 +266,9 @@ For compatibility a `query` property is also possible, which is an alias for the } ``` -Note that webpack needs to generate a unique module identifier from resource and all loaders including options. It tries to do this with a `JSON.stringify` of the options object. This is fine in 99.9% of cases, but may be not unique if you apply the same loaders with different options to the same resource and the options have some stringified values. It also breaks if the options object cannot be stringified (i.e. circular JSON). Because of this you can have a `ident` property in the options object which is used as unique identifier. +Note that webpack needs to generate a unique module identifier from the resource and all loaders including options. It tries to do this with a `JSON.stringify` of the options object. This is fine in 99.9% of cases, but may be not unique if you apply the same loaders with different options to the resource and the options have some stringified values. + +It also breaks if the options object cannot be stringified (i.e. circular JSON). Because of this you can have a `ident` property in the options object which is used as unique identifier. ## Module Contexts @@ -274,7 +283,7 @@ Example for an `expr` dynamic dependency: `require(expr)`. Example for an `wrapped` dynamic dependency: `require("./templates/" + expr)`. -Here are the available options with their defaults: +Here are the available options with their [defaults](https://github.com/webpack/webpack/blob/master/lib/WebpackOptionsDefaulter.js): ```js module: { @@ -289,6 +298,7 @@ module: { wrappedContextCritical: false wrappedContextRecursive: true, wrappedContextRegExp: /.*/, + strictExportPresence: false // since webpack 2.3.0 } ``` @@ -299,4 +309,4 @@ A few use cases: * Warn for dynamic dependencies: `wrappedContextCritical: true`. * `require(expr)` should include the whole directory: `exprContextRegExp: /^\.\//` * `require("./templates/" + expr)` should not include subdirectories by default: `wrappedContextRecursive: false` - +* `strictExportPresence` makes missing exports an error instead of warning diff --git a/content/configuration/node.md b/content/configuration/node.md index 6fc55b710497..eb2b3175bdb2 100644 --- a/content/configuration/node.md +++ b/content/configuration/node.md @@ -9,19 +9,21 @@ contributors: 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). + ## `node` `object` -This is an object where +This is an object where... + - each key is the name of a Node.js global or module - each value is one of the following - - `true`: Provide a polyfill. - - `"mock"`: Provide a mock that implements the expected interface but has little or no fuctionality. - - `"empty"`: Provide an empty object. - - `false`: Provide nothing. Code that expects this object to be defined may crash. +- `true`: Provide a polyfill. +- `"mock"`: Provide a mock that implements the expected interface but has little or no fuctionality. +- `"empty"`: Provide an empty object. +- `false`: Provide nothing. Code that expects this object to be defined may crash. -Note: not all properties support all of these values. See the sections below. +W> Note that not all properties support all of these values. See the sections below for more information. The defaults: @@ -37,6 +39,7 @@ node: { } ``` + ## `node.console` `boolean | "mock"` diff --git a/content/configuration/output.md b/content/configuration/output.md index ff218e4f5f24..52c1c95b3fb8 100644 --- a/content/configuration/output.md +++ b/content/configuration/output.md @@ -96,22 +96,27 @@ devtoolModuleFilenameTemplate: info => { If multiple modules would result in the same name, [`output.devtoolFallbackModuleFilenameTemplate`](#output-devtoolfallbackmodulefilenametemplate) is used instead for these modules. + ## `output.hashFunction` The hashing algorithm to use, defaults to `'md5'`. All functions from Node.JS' [`crypto.createHash`](https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm) are supported. + ## `output.hashDigest` The hashing algorithm to use, defaults to `'hex'`. All functions from Node.JS' [`hash.digest`](https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding) are supported. + ## `output.hashDigestLength` The prefix length of the hash digest to use, defaults to `20`. + ## `output.hashSalt` An optional salt to update the hash via Node.JS' [`hash.update`](https://nodejs.org/api/crypto.html#crypto_hash_update_data_input_encoding). + ## `output.filename` `string` @@ -269,7 +274,8 @@ var MyLibrary = _entry_return_; // your users will use your library like: MyLibrary.doSomething(); ``` -(Not specifying a `output.library` will cancel this var configuration) + +W> Not specifying a `output.library` will cancel this `"var"` configuration. `libraryTarget: "this"` - When your library is loaded, the **return value of your entry point** will be assigned to this, the meaning of `this` is up to you: @@ -338,8 +344,8 @@ define([], function() { //what this module returns is what your entry chunk returns }); ``` -But if you download this script, first you may get a error: `define is not defined`, it’s ok! -If you are distributing your library with AMD, then your users need to use RequireJS to load it. + +But if you download this script, you may get an error: `define is not defined`, it’s ok! If you are distributing your library with AMD, then your users need to use RequireJS to load it. Now that you have RequireJS loaded, you can load your library. @@ -384,6 +390,7 @@ output: { ``` And finally the output is: + ```javascript (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') @@ -531,12 +538,34 @@ There is no need to change it. `boolean` -Tell webpack to remove a module from cache if it throws an exception when it is `require`d. +Tell webpack to remove a module from the module instance cache (`require.cache`) if it throws an exception when it is `require`d. It defaults to `false` for performance reasons. When set to `false`, the module is not removed from cache, which results in the exception getting thrown only on the first `require` call (making it incompatible with node.js). +For instance, consider `module.js`: + +``` js +throw new Error("error"); +``` + +With `strictModuleExceptionHandling` set to `false`, only the first `require` throws an exception: + +``` js +// with strictModuleExceptionHandling = false +require("module") // <- throws +require("module") // <- doesn't throw +``` + +Instead, with `strictModuleExceptionHandling` set to `true`, all `require`s of this module throw an exception: + +``` js +// with strictModuleExceptionHandling = true +require("module") // <- throws +require("module") // <- also throw +``` + ## `output.umdNamedDefine` diff --git a/content/configuration/plugins.md b/content/configuration/plugins.md index 71343bc0d8b1..79f377478b86 100644 --- a/content/configuration/plugins.md +++ b/content/configuration/plugins.md @@ -11,6 +11,7 @@ The `plugins` option is used to customize the webpack build process in a variety T> Note: This page only discusses using plugins, however if you are interested in writing your own please visit [Writing a Plugin](/development/how-to-write-a-plugin/). + ## `plugins` `array` @@ -26,6 +27,7 @@ plugins: [ ``` A more complex example, using multiple plugins, might look something like this: + ```js var webpack = require('webpack') // importing plugins that do not come by default in webpack diff --git a/content/development/how-to-write-a-plugin.md b/content/development/how-to-write-a-plugin.md index 7eeb2793f3d7..4fa6975eb2c3 100644 --- a/content/development/how-to-write-a-plugin.md +++ b/content/development/how-to-write-a-plugin.md @@ -9,11 +9,11 @@ Plugins expose the full potential of the webpack engine to third-party developer A plugin for `webpack` consists of - - A named JavaScript function. - - Defines `apply` method in it's prototype. - - Specifies webpack's event hook to attach itself. - - Manipulates webpack internal instance specific data. - - Invokes webpack provided callback after functionality is complete. +- A named JavaScript function. +- Defines `apply` method in it's prototype. +- Specifies webpack's event hook to attach itself. +- Manipulates webpack internal instance specific data. +- Invokes webpack provided callback after functionality is complete. ```javascript // A named JavaScript function. diff --git a/content/guides/author-libraries.md b/content/guides/author-libraries.md index b06de4272b90..aa599a328e02 100644 --- a/content/guides/author-libraries.md +++ b/content/guides/author-libraries.md @@ -8,11 +8,13 @@ contributors: webpack is a tool which can be used to bundle application code and also to bundle library code. If you are the author of a JavaScript library and are looking to streamline your bundle strategy then this document will help you. + ## Author a Library Let's assume that you are writing a small library `webpack-numbers` allowing to convert numbers 1 to 5 from their numeric to a textual representation and vice-versa. The implementation makes use of ES2015 modules, and might look like this: __src/index.js__ + ```javascript import _ from 'lodash'; import numRef from './ref.json'; @@ -65,14 +67,17 @@ webpackNumbers.numToWord(3); // output is Three For full library configuration and code please refer to [webpack-library-example](https://github.com/kalcifer/webpack-library-example) + ## Configure webpack Now the agenda is to bundle this library - - Without bundling `lodash` but requiring it to be loaded by the consumer. - - Name of the library is `webpack-numbers` and the variable is `webpackNumbers`. - - Library can be imported as `import webpackNumbers from 'webpack-numbers'` or `require('webpack-numbers')`. - - Library can be accessed through global variable `webpackNumbers` when included through `script` tag. - - Library can be accessed inside Node.js. + +- Without bundling `lodash` but requiring it to be loaded by the consumer. +- Name of the library is `webpack-numbers` and the variable is `webpackNumbers`. +- Library can be imported as `import webpackNumbers from 'webpack-numbers'` or `require('webpack-numbers')`. +- Library can be accessed through global variable `webpackNumbers` when included through `script` tag. +- Library can be accessed inside Node.js. + ### Add webpack @@ -95,6 +100,7 @@ module.exports = { This adds basic configuration to bundle the library. + ### Add `externals` Now, if you run `webpack`, you will find that a largish bundle file is created. If you inspect the file, you will find that lodash has been bundled along with your code. @@ -121,6 +127,7 @@ module.exports = { This means that your library expects a dependency named `lodash` to be available in the consumer's environment. + ### Add `libraryTarget` For widespread use of the library, we would like it to be compatible in different environments, i. e. CommonJS, AMD, Node.js and as a global variable. @@ -159,6 +166,7 @@ module.exports = { If `library` is set and `libraryTarget` is not, `libraryTarget` defaults to `var` as specified in the [config reference](/configuration/output). + ### Final Steps [Tweak your production build using webpack](/guides/production-build). diff --git a/content/guides/caching.md b/content/guides/caching.md index 42955abd8b31..3dec7a11ac2a 100644 --- a/content/guides/caching.md +++ b/content/guides/caching.md @@ -12,9 +12,10 @@ To enable long-term caching of static resources produced by webpack: 2. Extract the webpack manifest into a separate file. 3. Ensure that the entry point chunk containing the bootstrapping code doesn’t change hash over time for the same set of dependencies. - For even more optimized setup: -4. Use compiler stats to get the file names when requiring resources in HTML. -5. Generate the chunk manifest JSON and inline it into the HTML page before loading resources. +For an even more optimized setup: + +1. Use compiler stats to get the file names when requiring resources in HTML. +2. Generate the chunk manifest JSON and inline it into the HTML page before loading resources. ## The problem @@ -64,6 +65,7 @@ vendor.2a6c1fee4b5b0d2c9285.js 2.58 kB 0 [emitted] vendor But the problem here is, builds after *any file update* will update all filenames and clients will have to re-download all application code. So how can we guarantee that clients always get the latest versions of assets without re-downloading all of them? + ## Generating unique hashes for each file What if we could produce the same filename, if the contents of the file did not change between builds? For example, it would be unnecessary to re-download a vendor file, when no dependencies have been updated, only application code. @@ -96,6 +98,7 @@ vendor.50cfb8f89ce2262e5325.js 2.58 kB 0 [emitted] vendor T> Don’t use [chunkhash] in development since this will increase compilation time. Separate development and production configs and use [name].js for development and [name].[chunkhash].js in production. + ## Get filenames from webpack compilation stats When working in development mode, you just reference JavaScript files by entry point name in your HTML. @@ -146,6 +149,7 @@ A sample output when using `WebpackManifestPlugin` in our config looks like: } ``` + ## Deterministic hashes To minimize the size of generated files, webpack uses identifiers instead of module names. During compilation, identifiers are generated, mapped to chunk filenames and then put into a JavaScript object called *chunk manifest*. @@ -237,7 +241,7 @@ module.exports = { Using this config the vendor chunk should not be changing its hash, unless you update its code or dependencies. Here is a sample output for 2 runs with `moduleB.js` being changed between the runs: -```bash +``` bash > node_modules/.bin/webpack Hash: f0ae5bf7c6a1fd3b2127 @@ -249,7 +253,8 @@ Time: 102ms chunk-manifest.json 73 bytes [emitted] manifest.d41d8cd98f00b204e980.js 5.56 kB 2 [emitted] manifest ``` -```bash + +``` bash > node_modules/.bin/webpack Hash: b5fb8e138b039ab515f3 @@ -264,12 +269,14 @@ manifest.d41d8cd98f00b204e980.js 5.56 kB 2 [emitted] manifest Notice that **vendor chunk has the same filename**, and **so does the manifest** since we’ve extracted the manifest chunk! + ## Manifest inlining Inlining the chunk manifest and webpack runtime (to prevent extra HTTP requests), depends on your server setup. There is a nice [walkthrough for Rails-based projects](https://brigade.engineering/setting-up-webpack-with-rails-c62aea149679). For server-side rendering in Node.js you can use [webpack-isomorphic-tools](https://github.com/halt-hammerzeit/webpack-isomorphic-tools). T> If your application doesn’t rely on any server-side rendering, it’s often enough to generate a single `index.html` file for your application. To do so, use i.e. [`HtmlWebpackPlugin`](https://github.com/ampedandwired/html-webpack-plugin) in combination with [`ScriptExtHtmlWebpackPlugin`](https://github.com/numical/script-ext-html-webpack-plugin) or [`InlineManifestWebpackPlugin`](https://github.com/szrenwei/inline-manifest-webpack-plugin). It will simplify the setup dramatically. + ## References * https://medium.com/@okonetchnikov/long-term-caching-of-static-assets-with-webpack-1ecb139adb95#.vtwnssps4 diff --git a/content/guides/code-splitting-async.md b/content/guides/code-splitting-async.md index 7f22184a84ea..2e356edc366d 100644 --- a/content/guides/code-splitting-async.md +++ b/content/guides/code-splitting-async.md @@ -13,6 +13,7 @@ This guide documents how to split your bundle into chunks which can be downloade webpack supports two similar techniques to achieve this goal: using `import()` (preferred, ECMAScript proposal) and `require.ensure()` (legacy, webpack specific). + ## Dynamic import: `import()` Currently, a "function-like" `import()` module loading [syntax proposal](https://github.com/tc39/proposal-dynamic-import) is on the way into ECMAScript. @@ -22,7 +23,8 @@ The [ES2015 Loader spec](https://whatwg.github.io/loader/) defines `import()` as webpack treats `import()` as a split-point and puts the requested module in a separate chunk. `import()` takes the module name as argument and returns a `Promise`: `import(name) -> Promise` -**index.js** +__index.js__ + ```javascript function determineDate() { import('moment').then(function(moment) { @@ -47,6 +49,7 @@ W> `import()` relies on [`Promise`](https://developer.mozilla.org/en-US/docs/Web 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). In an entry point of your application: + ```javascript import Es6Promise from 'es6-promise'; Es6Promise.polyfill(); @@ -60,6 +63,16 @@ if (!window.Promise) { // or ... ``` + +### Chunk names + +Since webpack 2.4.0, chunk names for dynamic imports can be specified using a "magic comment". + +```javascript +import(/* webpackChunkName: "my-chunk-name" */ 'module'); +``` + + ### Usage with Babel If you want to use `import` with [Babel](http://babeljs.io/), you'll need to install/add the [`syntax-dynamic-import`](http://babeljs.io/docs/plugins/syntax-dynamic-import/) plugin while it's still Stage 3 to get around the parser error. When the proposal is added to the spec this won't be necessary anymore. @@ -70,7 +83,8 @@ npm install --save-dev babel-core babel-loader babel-plugin-syntax-dynamic-impor npm install --save moment ``` -**index-es2015.js** +__index-es2015.js__ + ```javascript function determineDate() { import('moment') @@ -82,7 +96,8 @@ function determineDate() { determineDate(); ``` -**webpack.config.js** +__webpack.config.js__ + ```javascript module.exports = { entry: './index-es2015.js', @@ -105,10 +120,12 @@ module.exports = { }; ``` -Not using the `syntax-dynamic-import` plugin will fail the build with +Not using the `syntax-dynamic-import` plugin will fail the build with: + * `Module build failed: SyntaxError: 'import' and 'export' may only appear at the top level`, or * `Module build failed: SyntaxError: Unexpected token, expected {` + ### Usage with Babel and `async`/`await` To use ES2017 [`async`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)/[`await`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await) with `import()`: @@ -117,7 +134,8 @@ To use ES2017 [`async`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/ npm install --save-dev babel-plugin-transform-async-to-generator babel-plugin-transform-regenerator babel-plugin-transform-runtime ``` -**index-es2017.js** +__index-es2017.js__ + ```javascript async function determineDate() { const moment = await import('moment'); @@ -127,7 +145,8 @@ async function determineDate() { determineDate().then(str => console.log(str)); ``` -**webpack.config.js** +__webpack.config.js__ + ```javascript module.exports = { entry: './index-es2017.js', @@ -155,22 +174,12 @@ module.exports = { }; ``` -### `import` supersedes `require.ensure`? - -Good news: Failure to load a chunk can be handled now because they are `Promise` based. - -Caveat: `require.ensure` allows for easy chunk naming with the optional third argument, but `import` API doesn't offer that capability yet. If you want to keep that functionality, you can continue using `require.ensure`. - -```javascript -require.ensure([], function(require) { - var foo = require("./module"); -}, "custom-chunk-name"); -``` ### `System.import` is deprecated 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 [v2.1.0-beta.28](https://github.com/webpack/webpack/releases/tag/v2.1.0-beta.28) in favor of `import()`. + ## `require.ensure()` W> `require.ensure()` is specific to webpack and superseded by `import()`. @@ -180,16 +189,18 @@ webpack statically parses for `require.ensure()` in the code while building. Any The syntax is as follows: ```javascript -require.ensure(dependencies: String[], callback: function(require), chunkName: String) +require.ensure(dependencies: String[], callback: function(require), errorCallback: function(error), chunkName: String) ``` * `dependencies` is an array of strings where we can declare all the modules that need to be made available before all the code in the callback function can be executed. * `callback` is 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. -* `chunkName` is 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. +* optional: `errorCallback` is a function that is executed when webpack fails to load the dependencies. +* optional: `chunkName` is 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. Let's reconsider the dynamic import of `moment` from the `import()` section and rewrite it using `require.ensure()`: -**index.js** +__index.js__ + ```javascript function determineDate() { require.ensure([], function(require) { @@ -203,7 +214,8 @@ determineDate(); Running `webpack index.js bundle.js` generates two files, `bundle.js` and `0.bundle.js`: -**bundle.js** +__bundle.js__ + ```js // webpack code ... /***/ (function(module, exports, __webpack_require__) { @@ -219,7 +231,8 @@ determineDate(); // webpack code ... ``` -**0.bundle.js* +__0.bundle.js__ + ```js webpackJsonp([0],[(function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(module) { @@ -231,10 +244,36 @@ webpackJsonp([0],[(function(module, exports, __webpack_require__) { When you add `bundle.js` in your HTML file and open it in your browser, the `0.bundle.js` will be loaded asynchronously by webpack. + ### publicPath `output.publicPath` is an important option when using code-splitting, it is used to tell webpack where to load your bundles on-demand, see the [configuration documentation](/configuration/output/#output-publicpath). + +### Chunk name + +```javascript +require.ensure([], function(require) { + var foo = require('./module'); +}, 'custom-chunk-name'); +``` + +Use the last argument to `require.ensure()` in order to specify the name of the chunk. + + +### Error callback + +Since webpack 2.4.0, an error callback can be as third argument to `require.ensure()`. This allows to address errors which occur when dynamically loading the chunk: + +```javascript +require.ensure([], function(require) { + var foo = require('./module'); +}, function(err) { + console.error('We failed to load chunk: ' + err); +}, 'custom-chunk-name'); +``` + + ### Empty Array as Parameter ```javascript @@ -245,6 +284,7 @@ require.ensure([], function(require){ The above code ensures that a split point is created and `a.js` is bundled separately by webpack. + ### Dependencies as Parameter ```javascript @@ -256,7 +296,9 @@ require.ensure(['./b.js'], function(require) { In the above code, `b.js` and `c.js` are bundled together and split from the main bundle. But only the contents of `c.js` are executed. The contents of `b.js` are only made available and not executed. To execute `b.js`, we will have to require it in a sync manner like `require('./b.js')` for the JavaScript to get executed. + ## Examples + * `import()` * * https://github.com/webpack/webpack/tree/master/examples/harmony * * https://github.com/webpack/webpack/tree/master/examples/code-splitting-harmony diff --git a/content/guides/code-splitting-css.md b/content/guides/code-splitting-css.md index b61b4c57bbdf..9b699fbefa08 100644 --- a/content/guides/code-splitting-css.md +++ b/content/guides/code-splitting-css.md @@ -7,10 +7,12 @@ contributors: - johnstew - simon04 - shinxi + - tomtasche --- To bundle CSS files with webpack, import CSS into your JavaScript code like [any other module](/concepts/modules), and use the `css-loader` (which outputs the CSS as JS module), and optionally apply the `ExtractTextWebpackPlugin` (which extracts the bundled CSS and outputs CSS files). + ## Importing CSS Import the CSS file like a JavaScript module, for instance in `vendor.js`: @@ -19,32 +21,41 @@ Import the CSS file like a JavaScript module, for instance in `vendor.js`: import 'bootstrap/dist/css/bootstrap.css'; ``` -## Using `css-loader` -Configure the [`css-loader`](/loaders/css-loader) in `webpack.config.js` as follows: +## Using `css-loader` and `style-loader` + +Install the [`css-loader`](/loaders/css-loader) and [`style-loader`](/loaders/style-loader): + +``` bash +npm install --save-dev css-loader style-loader +``` + +Configure it in `webpack.config.js` as follows: ```javascript module.exports = { module: { rules: [{ test: /\.css$/, - use: 'css-loader' + use: [ 'style-loader', 'css-loader' ] }] } } ``` -As a result, the CSS is bundled along with your JavaScript. +As a result, the CSS is bundled along with your JavaScript and applied to the page via a `