Webpack-dev-server can be used to quickly develop an application. See the development guide to get started. This page describes the options that affect the behavior of webpack-dev-server (short: dev-server). Options that are compatible with webpack-dev-middleware have ? next to them. Webpack is a tool that allows you to compile, for example, JavaScript modules into one JS file. If you have a large number of files, it creates one large file (or several files) to run your. Webpack -watch does not work on Windows (nor webpack-dev-server). And only after ctrl+c it will unblock my. Webpack -watch does not work nor webpack-dev. Jul 31, 2017 I just use 'Ctrl + c' twice,stop the webpack-dev-server Answer 2 use it as inline might help. It searches for the config file in the root directory.So -config is preferably used only when the config file is somewhere deep in the directory. 當在開發前端的時候,需要一個簡單的 server ,就可以用這個套件 # 前置作業 首先要有安裝過 node.js 和 npm 套件管理工具 # 安裝 透過 npm 安裝即可 ``` bash npm install. Aug 14, 2017 Launch webpack-dev-server. Ctrl-C to kill the process. Launch again. Address in use suggests the first http server was not properly shut down.
This article is featured in our book, Modern JavaScript Tools & Skills. Get familiar with the essential tools that support Modern JavaScript development.
The Webpack 4 docs state that:
Webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.
Webpack has become one of the most important tools for modern web development. It’s primarily a module bundler for your JavaScript, but it can be taught to transform all of your front-end assets like HTML, CSS, even images. It can give you more control over the number of HTTP requests your app is making and allows you to use other flavors of those assets (Pug, Sass, and ES8, for example). Webpack also allows you to easily consume packages from npm.
This article is aimed at those who are new to Webpack, and will cover initial setup and configuration, modules, loaders, plugins, code splitting and hot module replacement. If you find video tutorials helpful, I can highly recommend Glen Maddern’s Webpack from First Principles as a starting point to understand what it is that makes Webpack special. It’s a little old now, but the principles are still the same, and it’s a great introduction.
To follow along at home, you’ll need to have Node.js installed. You can also download the demo app from our GitHub repo.
Setup
Let’s initialize a new project with npm and install
webpack and webpack-cli :
Next we’ll create the following directory structure and contents:
dist/index.html
src/index.js
webpack.config.js
This tells Webpack to compile the code in our entry point
src/index.js and output a bundle in /dist/bundle.js . Let’s add an npm script for running Webpack.
package.json
Using the
npm run develop command, we can create our first bundle!
You should now be able to load
dist/index.html in your browser and be greeted with “Hello Webpack”.
Open up
dist/bundle.js to see what Webpack has done. At the top is Webpack’s module bootstrapping code, and right at the bottom is our module. You may not be colored impressed just yet, but if you’ve come this far you can now start using ES Modules, and Webpack will be able to produce a bundle for production that will work in all browsers.
Restart the build with Ctrl + C and run
npm run build to compile our bundle in production mode.
Notice that the bundle size has come down from 2.92 KiB to 647 bytes.
Take another look at
dist/bundle.js and you’ll see an ugly mess of code. Our bundle has been minified with UglifyJS: the code will run exactly the same, but it’s done with the smallest file size possible.
Modules
Using ES Modules, you can split up your large programs into many small, self-contained programs.
Out of the box, Webpack knows how to consume ES Modules using
import and export statements. As an example, let’s try this out now by installing lodash-es and adding a second module:
src/index.js
src/people.js
Run
npm run develop to start Webpack and refresh index.html . You should see an array of people grouped by manager printed to the screen.
Note: Imports without a relative path like
'es-lodash' are modules from npm installed to /node_modules . Your own modules will always need a relative path like './people' , as this is how you can tell them apart.
Notice in the console that our bundle size has increased to 1.41 MiB! This is worth keeping an eye on, though in this case there’s no cause for concern. Using
npm run build to compile in production mode, all of the unused lodash modules from lodash-es are removed from bundle. This process of removing unused imports is known as tree-shaking, and is something you get for free with Webpack.
Loaders
Loaders let you run preprocessors on files as they’re imported. This allows you to bundle static resources beyond JavaScript, but let’s look at what can be done when loading
.js modules first.
Let’s keep our code modern by running all
.js files through the next-generation JavaScript transpiler Babel:
webpack.config.js
.babelrc
This config prevents Babel from transpiling
import and export statements into ES5, and enables dynamic imports — which we’ll look at later in the section on Code Splitting.
We’re now free to use modern language features, and they’ll be compiled down to ES5 that runs in all browsers.
Sass
Loaders can be chained together into a series of transforms. A good way to demonstrate how this works is by importing Sass from our JavaScript:
webpack.config.js
These loaders are processed in reverse order:
You can think of these as function calls. The output of one loader feeds as input into the next:
Let’s add a Sass source file and import is a module.
src/style.scss
src/index.js
Restart the build with Ctrl + C and
npm run develop . Refresh index.html in the browser and you should see some styling.
CSS in JS
We just imported a Sass file from our JavaScript, as a module.
Open up
dist/bundle.js and search for “pre {”. Indeed, our Sass has been compiled to a string of CSS and saved as a module within our bundle. When we import this module into our JavaScript, style-loader outputs that string into an embedded <style> tag.
Why would you do such a thing?
I won’t delve too far into this topic here, but here are a few reasons to consider:
Images
The last example of loaders we’ll look at is the handling of images with
file-loader .
In a standard HTML document, images are fetched when the browser encounters an
img tag or an element with a background-image property. With Webpack, you can optimize this in the case of small images by storing the source of the images as strings inside your JavaScript. By doing this, you preload them and the browser won’t have to fetch them with separate requests later:
webpack.config.js
Download a test image with this command:
Restart the build with Ctrl + C and
npm run develop and you’ll now be able to import images as modules!
src/index.js
src/image-example.js
This will include an image where the
src attribute contains a data URI of the image itself:
Auto-Tune Pro is the most complete and advanced edition of Auto Tune for Windows PC. Added automatic key detection with the new Auto-Key plug-in (included with Auto Tune purchase), Classic Mode for the “Auto-Tune 5 sound,” real-time MIDI Control, and ARA for closer integration with supported DAWs.Both the Auto Mode and Graph Mode interfaces have been redesigned to offer the most efficient, flexible, and intuitive workflow for professional users and beginners alike. It includes both Auto Mode, for real-time pitch correction and effects, and Graph Mode, for detailed pitch and time editing.
Background images in our CSS are also processed by
file-loader .
src/style.scss
See more examples of Loaders in the docs:
Dependency Graph
You should now be able to see how loaders help to build up a tree of dependencies amongst your assets. This is what the image on the Webpack home page is demonstrating.
Though JavaScript is the entry point, Webpack appreciates that your other asset types — like HTML, CSS, and SVG — each have dependencies of their own, which should be considered as part of the build process.
Code Splitting
From the Webpack docs:
Code splitting is one of the most compelling features of Webpack. This feature allows you to split your code into various bundles which can then be loaded on demand or in parallel. It can be used to achieve smaller bundles and control resource load prioritization which, if used correctly, can have a major impact on load time.
So far, we’ve only seen a single entry point —
src/index.js — and a single output bundle — dist/bundle.js . When your app grows, you’ll need to split this up so that the entire codebase isn’t downloaded at the start. A good approach is to use Code Splitting and Lazy Loading to fetch things on demand as the code paths require them.
Let’s demonstrate this by adding a “chat” module, which is fetched and initialized when someone interacts with it. We’ll make a new entry point and give it a name, and we’ll also make the output’s filename dynamic so it’s different for each chunk.
webpack.config.js
src/app.js
src/chat.js
src/app.scss
Note: Despite the
/* webpackChunkName */ comment for giving the bundle a name, this syntax is not Webpack specific. It’s the proposed syntax for dynamic imports intended to be supported directly in the browser.
Let’s run
npm run build and see what this generates:
As our entry bundle has changed, we’ll need to update our path to it as well.
dist/index.html
Let’s start up a server from the dist directory to see this in action:
Open http://localhost:5000 in the browser and see what happens. Only
bundle.js is fetched initially. When the button is clicked, the chat module is imported and initialized.
With very little effort, we’ve added dynamic code splitting and lazy loading of modules to our app. This is a great starting point for building a highly performant web app.
Plugins
While loaders operate transforms on single files, plugins operate across larger chunks of code.
Now that we’re bundling our code, external modules and static assets, our bundle will grow — quickly. Plugins are here to help us split our code in clever ways and optimize things for production.
Without knowing it, we’ve actually already used many default Webpack plugins with “mode”
development
production
Production
Before adding additional plugins, we’ll first split our config up so that we can apply plugins specific to each environment.
Rename
webpack.config.js to webpack.common.js and add a config file for development and production.
We’ll use
webpack-merge to combine our common config with the environment-specific config:
webpack.dev.js
webpack.prod.js
package.json
Now we can add plugins specific to development into
webpack.dev.js and plugins specific to production in webpack.prod.js .
Split CSS
It’s considered best practice to split your CSS from your JavaScript when bundling for production using ExtractTextWebpackPlugin.
The current
.scss loaders are perfect for development, so we’ll move those from webpack.common.js into webpack.dev.js and add ExtractTextWebpackPlugin to webpack.prod.js only.
webpack.common.js
webpack.dev.js
webpack.prod.js
Let’s compare the output of our two build scripts:
Now that our CSS is extracted from our JavaScript bundle for production, we need to
<link> to it from our HTML.
dist/index.html
This allows for parallel download of the CSS and JavaScript in the browser, so will be faster-loading than a single bundle. It also allows the styles to be displayed before the JavaScript finishes downloading.
Generating HTML
Whenever our outputs have changed, we’ve had to keep updating
index.html to reference the new file paths. This is precisely what html-webpack-plugin was created to do for us automatically.
We may as well add
clean-webpack-plugin at the same time to clear out our /dist directory before each build.
webpack.common.js
Now every time we build, dist will be cleared out. We’ll now see
index.html output too, with the correct paths to our entry bundles.
Running
npm run develop produces this:
And
npm run build produces this:
Development
The webpack-dev-server provides you with a simple web server and gives you live reloading, so you don’t need to manually refresh the page to see changes.
package.json
Open up http://localhost:8080/ in the browser and make a change to one of the JavaScript or CSS files. You should see it build and refresh automatically.
HotModuleReplacement
The
HotModuleReplacement plugin goes one step further than Live Reloading and swaps out modules at runtime without the refresh. When configured correctly, this saves a huge amount of time during development of single page apps. Where you have a lot of state in the page, you can make incremental changes to components, and only the changed modules are replaced and updated.
webpack.dev.js
Now we need to accept changed modules from our code to re-initialize things.
src/app.js
Note: When Hot Module Replacement is enabled,
module.hot is set to true for development and false for production, so these are stripped out of the bundle.
Restart the build and see what happens when we do the following:
Here’s what’s happening:
CSS Replacement
Let’s change the button color to red and see what happens:
src/app.scss
Now we get to see instant updates to our styles without losing any state. This is a much-improved developer experience! And it feels like the future.
HTTP/2
One of the primary benefits of using a module bundler like Webpack is that it can help you improve performance by giving you control over how the assets are built and then fetched on the client. It has been considered best practice for years to concatenate files to reduce the number of requests that need to be made on the client. This is still valid, but HTTP/2 now allows multiple files to be delivered in a single request, so concatenation isn’t a silver bullet anymore. Your app may actually benefit from having many small files individually cached. The client could then fetch a single changed module rather than having to fetch an entire bundle again with mostly the same contents.
The creator of Webpack, Tobias Koppers, has written an informative post explaining why bundling is still important, even in the HTTP/2 era.
Read more about this over at Webpack & HTTP/2.
Over to You
I hope you’ve found this introduction to Webpack helpful and are able to start using it to great effect. It can take a little time to wrap your head around Webpack’s configuration, loaders and plugins, but learning how this tool works will pay off.
The documentation for Webpack 4 is currently being worked on, but is really well put together. I highly recommend reading through the Concepts and Guides for more information. Here’s a few other topics you may be interested in:
Is Webpack 4 your module bundler of choice? Let me know in the comments below.
This article is featured in our book, Modern JavaScript Tools & Skills. Get familiar with the essential tools that support Modern JavaScript development.
The Webpack 4 docs state that:
Webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.
Webpack has become one of the most important tools for modern web development. It’s primarily a module bundler for your JavaScript, but it can be taught to transform all of your front-end assets like HTML, CSS, even images. It can give you more control over the number of HTTP requests your app is making and allows you to use other flavors of those assets (Pug, Sass, and ES8, for example). Webpack also allows you to easily consume packages from npm.
This article is aimed at those who are new to Webpack, and will cover initial setup and configuration, modules, loaders, plugins, code splitting and hot module replacement. If you find video tutorials helpful, I can highly recommend Glen Maddern’s Webpack from First Principles as a starting point to understand what it is that makes Webpack special. It’s a little old now, but the principles are still the same, and it’s a great introduction.
To follow along at home, you’ll need to have Node.js installed. You can also download the demo app from our GitHub repo.
Setup
Let’s initialize a new project with npm and install
webpack and webpack-cli :
Next we’ll create the following directory structure and contents:
dist/index.html
src/index.js
webpack.config.js
This tells Webpack to compile the code in our entry point
src/index.js and output a bundle in /dist/bundle.js . Let’s add an npm script for running Webpack.
package.json
Using the
npm run develop command, we can create our first bundle!
You should now be able to load
dist/index.html in your browser and be greeted with “Hello Webpack”.
Open up
dist/bundle.js to see what Webpack has done. At the top is Webpack’s module bootstrapping code, and right at the bottom is our module. You may not be colored impressed just yet, but if you’ve come this far you can now start using ES Modules, and Webpack will be able to produce a bundle for production that will work in all browsers.
Restart the build with Ctrl + C and run
npm run build to compile our bundle in production mode.
Notice that the bundle size has come down from 2.92 KiB to 647 bytes.
Take another look at
dist/bundle.js and you’ll see an ugly mess of code. Our bundle has been minified with UglifyJS: the code will run exactly the same, but it’s done with the smallest file size possible.
Modules
Using ES Modules, you can split up your large programs into many small, self-contained programs.
Out of the box, Webpack knows how to consume ES Modules using
import and export statements. As an example, let’s try this out now by installing lodash-es and adding a second module:
src/index.js
src/people.js
Run
npm run develop to start Webpack and refresh index.html . You should see an array of people grouped by manager printed to the screen.
Note: Imports without a relative path like
'es-lodash' are modules from npm installed to /node_modules . Your own modules will always need a relative path like './people' , as this is how you can tell them apart.
Notice in the console that our bundle size has increased to 1.41 MiB! This is worth keeping an eye on, though in this case there’s no cause for concern. Using
npm run build to compile in production mode, all of the unused lodash modules from lodash-es are removed from bundle. This process of removing unused imports is known as tree-shaking, and is something you get for free with Webpack.
Loaders
Loaders let you run preprocessors on files as they’re imported. This allows you to bundle static resources beyond JavaScript, but let’s look at what can be done when loading
.js modules first.
Let’s keep our code modern by running all
.js files through the next-generation JavaScript transpiler Babel:
webpack.config.js
.babelrc
This config prevents Babel from transpiling
import and export statements into ES5, and enables dynamic imports — which we’ll look at later in the section on Code Splitting.
We’re now free to use modern language features, and they’ll be compiled down to ES5 that runs in all browsers.
Sass
Loaders can be chained together into a series of transforms. A good way to demonstrate how this works is by importing Sass from our JavaScript:
webpack.config.js
These loaders are processed in reverse order:
You can think of these as function calls. The output of one loader feeds as input into the next:
Let’s add a Sass source file and import is a module.
src/style.scss
src/index.js
Restart the build with Ctrl + C and
npm run develop . Refresh index.html in the browser and you should see some styling.
CSS in JS
We just imported a Sass file from our JavaScript, as a module.
Open up
dist/bundle.js and search for “pre {”. Indeed, our Sass has been compiled to a string of CSS and saved as a module within our bundle. When we import this module into our JavaScript, style-loader outputs that string into an embedded <style> tag.
Why would you do such a thing?
I won’t delve too far into this topic here, but here are a few reasons to consider:
Images
The last example of loaders we’ll look at is the handling of images with
file-loader .
In a standard HTML document, images are fetched when the browser encounters an
img tag or an element with a background-image property. With Webpack, you can optimize this in the case of small images by storing the source of the images as strings inside your JavaScript. By doing this, you preload them and the browser won’t have to fetch them with separate requests later:
webpack.config.js
Download a test image with this command:
Restart the build with Ctrl + C and
npm run develop and you’ll now be able to import images as modules!
src/index.js
src/image-example.js
This will include an image where the
src attribute contains a data URI of the image itself:
Background images in our CSS are also processed by
file-loader .
src/style.scss
See more examples of Loaders in the docs:
Dependency Graph
You should now be able to see how loaders help to build up a tree of dependencies amongst your assets. This is what the image on the Webpack home page is demonstrating.
Though JavaScript is the entry point, Webpack appreciates that your other asset types — like HTML, CSS, and SVG — each have dependencies of their own, which should be considered as part of the build process.
Code Splitting
From the Webpack docs:
Code splitting is one of the most compelling features of Webpack. This feature allows you to split your code into various bundles which can then be loaded on demand or in parallel. It can be used to achieve smaller bundles and control resource load prioritization which, if used correctly, can have a major impact on load time.
So far, we’ve only seen a single entry point —
src/index.js — and a single output bundle — dist/bundle.js . When your app grows, you’ll need to split this up so that the entire codebase isn’t downloaded at the start. A good approach is to use Code Splitting and Lazy Loading to fetch things on demand as the code paths require them.
Let’s demonstrate this by adding a “chat” module, which is fetched and initialized when someone interacts with it. We’ll make a new entry point and give it a name, and we’ll also make the output’s filename dynamic so it’s different for each chunk.
webpack.config.js
src/app.js
src/chat.js
src/app.scss
Note: Despite the
/* webpackChunkName */ comment for giving the bundle a name, this syntax is not Webpack specific. It’s the proposed syntax for dynamic imports intended to be supported directly in the browser.
Let’s run
npm run build and see what this generates:
As our entry bundle has changed, we’ll need to update our path to it as well.
dist/index.html
Let’s start up a server from the dist directory to see this in action:
Open http://localhost:5000 in the browser and see what happens. Only
bundle.js is fetched initially. When the button is clicked, the chat module is imported and initialized.
With very little effort, we’ve added dynamic code splitting and lazy loading of modules to our app. This is a great starting point for building a highly performant web app.
Plugins
While loaders operate transforms on single files, plugins operate across larger chunks of code.
Now that we’re bundling our code, external modules and static assets, our bundle will grow — quickly. Plugins are here to help us split our code in clever ways and optimize things for production.
Without knowing it, we’ve actually already used many default Webpack plugins with “mode”
development
production
ProductionWebpack Dev Server Watch
Before adding additional plugins, we’ll first split our config up so that we can apply plugins specific to each environment.
Rename
webpack.config.js to webpack.common.js and add a config file for development and production.
We’ll use
webpack-merge to combine our common config with the environment-specific config:
webpack.dev.js
webpack.prod.js
package.json
Now we can add plugins specific to development into
webpack.dev.js and plugins specific to production in webpack.prod.js .
Split CSS
It’s considered best practice to split your CSS from your JavaScript when bundling for production using ExtractTextWebpackPlugin.
The current
.scss loaders are perfect for development, so we’ll move those from webpack.common.js into webpack.dev.js and add ExtractTextWebpackPlugin to webpack.prod.js only.
webpack.common.js
webpack.dev.js
webpack.prod.js
Let’s compare the output of our two build scripts:
Now that our CSS is extracted from our JavaScript bundle for production, we need to
<link> to it from our HTML.
dist/index.html
This allows for parallel download of the CSS and JavaScript in the browser, so will be faster-loading than a single bundle. It also allows the styles to be displayed before the JavaScript finishes downloading.
Generating HTML
Whenever our outputs have changed, we’ve had to keep updating
index.html to reference the new file paths. This is precisely what html-webpack-plugin was created to do for us automatically.
We may as well add
clean-webpack-plugin at the same time to clear out our /dist directory before each build.
webpack.common.js
Now every time we build, dist will be cleared out. We’ll now see
index.html output too, with the correct paths to our entry bundles.
Running
npm run develop produces this:
And
npm run build produces this:
Development
The webpack-dev-server provides you with a simple web server and gives you live reloading, so you don’t need to manually refresh the page to see changes.
package.json
Open up http://localhost:8080/ in the browser and make a change to one of the JavaScript or CSS files. You should see it build and refresh automatically.
HotModuleReplacement
The
HotModuleReplacement plugin goes one step further than Live Reloading and swaps out modules at runtime without the refresh. When configured correctly, this saves a huge amount of time during development of single page apps. Where you have a lot of state in the page, you can make incremental changes to components, and only the changed modules are replaced and updated.
webpack.dev.js
Now we need to accept changed modules from our code to re-initialize things.
Ctrl C Webpack Dev Server Disable Host Check
src/app.js
Note: When Hot Module Replacement is enabled,
module.hot is set to true for development and false for production, so these are stripped out of the bundle.
Restart the build and see what happens when we do the following:
Here’s what’s happening:
CSS Replacement
Let’s change the button color to red and see what happens:
src/app.scss
Now we get to see instant updates to our styles without losing any state. This is a much-improved developer experience! And it feels like the future.
HTTP/2
One of the primary benefits of using a module bundler like Webpack is that it can help you improve performance by giving you control over how the assets are built and then fetched on the client. It has been considered best practice for years to concatenate files to reduce the number of requests that need to be made on the client. This is still valid, but HTTP/2 now allows multiple files to be delivered in a single request, so concatenation isn’t a silver bullet anymore. Your app may actually benefit from having many small files individually cached. The client could then fetch a single changed module rather than having to fetch an entire bundle again with mostly the same contents.
The creator of Webpack, Tobias Koppers, has written an informative post explaining why bundling is still important, even in the HTTP/2 era.
Read more about this over at Webpack & HTTP/2.
Over to You
I hope you’ve found this introduction to Webpack helpful and are able to start using it to great effect. It can take a little time to wrap your head around Webpack’s configuration, loaders and plugins, but learning how this tool works will pay off.
Ctrl C Webpack Dev Server Download
The documentation for Webpack 4 is currently being worked on, but is really well put together. I highly recommend reading through the Concepts and Guides for more information. Here’s a few other topics you may be interested in:
Ctrl C Webpack Dev Server Https
Is Webpack 4 your module bundler of choice? Let me know in the comments below.
Comments are closed.
|