diff --git a/content/concepts/configuration.md b/content/concepts/configuration.md index 62406bacd8ba..6ff7c5dec29d 100644 --- a/content/concepts/configuration.md +++ b/content/concepts/configuration.md @@ -1,8 +1,25 @@ --- title: Configuration +contributors: --- -You may have noticed that few webpack configurations look exactly alike. This is because **webpack's configuration file is a JavaScript file that exports an object.** This object, is then parsed by webpack based upon its defined properties. +You may have noticed that few webpack configurations look exactly alike. This is because **webpack's configuration file is a JavaScript file that exports an object.** This object 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 JS controlflow expressions i. e. the `?:` operator +* use constants or variables for often used values +* write and execute function to generate a part of the configuration + +Use these features when appropriate. + +**You should NOT use the following things**. Technically you could use them, but it's **not recommended**: + +* Access CLI arguments, when using the webpack CLI (instead write your own CLI, or use `--env`) +* Export non-deterministic values (calling webpack twice should result in the same output files) +* Write very long configurations (instead split the configuration into multiple files) The following examples below describe how webpack's configuration object can be both expressive and configurable because _it is code_: @@ -35,8 +52,8 @@ var baseConfig = { entry: './entry.js' }, output: { - filename: '[name].js', - path: path.resolve(__dirname, 'dist') + path: path.resolve(__dirname, 'dist'), + filename: '[name].js' }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ diff --git a/content/concepts/entry-points.md b/content/concepts/entry-points.md index b2595350d0ff..a55b1a3e6fe1 100644 --- a/content/concepts/entry-points.md +++ b/content/concepts/entry-points.md @@ -1,6 +1,8 @@ --- title: Entry Points sort: 0 +contributors: + - TheLarkInn --- Like we mentioned in the [introduction](./), 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. @@ -73,6 +75,8 @@ const config = { **Why?** This setup allows you to leverage `CommonsChunkPlugin` and extract any vendor references from your app bundle into your vendor bundle, replacing them with `__webpack_require__()` calls. If there is no vendor code in your application bundle, then you can achieve a common pattern in webpack known as [long-term vendor-caching](/how-to/cache). +?> Consider removing this scenario in favor of the DllPlugin, which provides a better vendor-splitting. + #### Multi Page Application **webpack.config.js** @@ -82,16 +86,15 @@ const config = { entry: { pageOne: './src/pageOne/index.js', pageTwo: './src/pageTwo/index.js', - pageThree: './src/pageThree/index.js', - vendors: './src/vendors.js' + pageThree: './src/pageThree/index.js' } }; ``` -**What does this do?** We are telling webpack that we would like 4 separate dependency graphs (like the above example). +**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 `CommonsChunkPlugin` 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. -- Set up [long-term vendor-caching](/how-to/cache) with the same plugin and techniques seen in the first example. +T> As a rule of thumb: for one HTML use exactly one entry point. \ No newline at end of file diff --git a/content/concepts/index.md b/content/concepts/index.md index 48cff76f4e3d..5cb146971d3a 100644 --- a/content/concepts/index.md +++ b/content/concepts/index.md @@ -20,16 +20,14 @@ The simplest example is seen below: **webpack.config.js** ```javascript -const config = { +module.exports = { entry: './path/to/my/entry/file.js' }; - -module.exports = config; ``` There are multiple ways to declare your `entry` property that are specific to your application's needs. -[**Learn more!**](/concepts/entry-points) +[Learn more!](/concepts/entry-points) ## Output @@ -38,11 +36,11 @@ Once you've bundled all of your assets together, we still need to tell webpack * **webpack.config.js** ```javascript -const config = { +module.exports = { entry: './path/to/my/entry/file.js', output: { - filename: 'my-first-webpack.bundle.js', - path: './dist' + path: path.resolve(__dirname, 'dist'), + filename: 'my-first-webpack.bundle.js' } }; ``` @@ -53,7 +51,7 @@ T> You may see the term **emitted** or **emit** used throughout our documentatio The `output` property has [many more configurable features](/configuration), but let's spend some time understanding some of the most common use cases for the `output` property. -[**Learn more!**](/concepts/output) +[Learn more!](/concepts/output) ## Loaders @@ -65,7 +63,7 @@ The goal is to have all of the assets in your project to be **webpack's** concer At a high level, they have two purposes in your webpack config. 1. Identify what files should be transformed by a certain loader. (`test` property) -2. Transform that file so that it can be added to your dependency graph (and eventually your bundle). (`loader` property) +2. Transform that file so that it can be added to your dependency graph (and eventually your bundle). (`use` property) **webpack.config.js** @@ -73,26 +71,26 @@ At a high level, they have two purposes in your webpack config. const config = { entry: './path/to/my/entry/file.js', output: { - filename: 'my-first-webpack.bundle.js', - path: './dist' + path: path.resolve(__dirname, 'dist'), + filename: 'my-first-webpack.bundle.js' }, module: { - loaders: [ - {test: /\.(js|jsx)$/, loader: 'babel-loader'} + rules: [ + {test: /\.(js|jsx)$/, use: 'babel-loader'} ] } }; ``` -In the configuration above we have defined our loader with it's two required properties: `test`, and `loader`. This tells webpack's compiler the following: +In the configuration above we have defined a rules which used our loader with it's 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 '.js' or '.jsx' file inside of a `require()`/`import` statement, use the `babel-loader` to transform it before you add it to the bundle". +> "Hey webpack compiler, when you come across a path that resolves to a '.js' or '.jsx' file inside of a `require()`/`import` statement, **use** the `babel-loader` to transform it before you add it to the bundle". -W> It is important to remember when defining loaders in your webpack config, you are defining them under `module.loaders`, and not `loaders`. +W> It is important to remember when defining rules in your webpack config, you are defining them under `module.rules`, and not `rules`. But webpack will yell at you when doing this incorrectly. There are more specific properties to define on loaders that we haven't yet covered. -[**Learn more!**](/concepts/loaders) +[Learn more!](/concepts/loaders) ## Plugins @@ -130,4 +128,4 @@ There are many plugins that webpack provides out of the box! Check out our [list Using plugins in your webpack config is straight-forward, however there are many use-cases that are worth discussing further. -[**Learn more!**](/concepts/plugins) \ No newline at end of file +[Learn more!](/concepts/plugins) \ No newline at end of file diff --git a/content/concepts/loaders.md b/content/concepts/loaders.md index 80d15de95935..4c5b6631e912 100644 --- a/content/concepts/loaders.md +++ b/content/concepts/loaders.md @@ -1,6 +1,7 @@ --- title: Loaders sort: 2 +contributors: --- -> module.loaders configuration option -> test, include, exclude, loader, query + +?> Write about how rules work and what's the purpose of loaders. diff --git a/content/concepts/output.md b/content/concepts/output.md index c383f37b211f..8d31a49159cb 100644 --- a/content/concepts/output.md +++ b/content/concepts/output.md @@ -1,6 +1,7 @@ --- title: Output sort: 1 +contributors: --- Options affecting the output of the compilation. `output` options tell Webpack how to write the compiled files to disk. Note, that while there can be multiple `entry` points, only one `output` configuration is specified. diff --git a/content/concepts/plugins.md b/content/concepts/plugins.md index 038ad7b4b9f6..2d6174d02f08 100644 --- a/content/concepts/plugins.md +++ b/content/concepts/plugins.md @@ -6,7 +6,7 @@ contributors: - jhnns --- -**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!! +**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. @@ -31,6 +31,8 @@ ConsoleLogOnBuildWebpackPlugin.prototype.apply = function(compiler) { }; ``` +T> As clever JS 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. @@ -70,6 +72,8 @@ 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. + **some-node-script.js** ```javascript