官方定义:css
webpack is a module bundler lets you write any module format(mixed also), compiles then for the browser. And it supports static async bundling.html
简单的说webpack是一个构建工具,什么是构建工具呢,咱们在开发环境的代码,是为了方便阅读与开发,生产环境的代码则是为了代码更好的运行。开发环境的代码,要进行压缩编译之后,才能放在线上执行,这样代码体积更小,加载起来更快,因此构建工具通常有如下几种做用:vue
将JS、CSS代码混淆压缩,让代码体积更小,加载更快node
编写CSS时使用Less、Sass,编写JS时使用ES六、TypeScript等,这些标准目前都没法被浏览器兼容,所以须要构建工具编译,例如使用Babel编译ES6语法。react
CSS和JS的模块化语法,目前都没法被浏览器兼容。所以开发环境可使用既定的模块化语法,可是须要构建工具将模块化语法编译为浏览器可识别形式。例如使用webpack、Rollup等处理JS模块化。webpack
以前写过一篇关于模块化的文章,不论是AMD仍是CMD,都是runtime的时候进行的,且浏览器的支持性还不是特别好,须要一个东西来进行转化。web
一个web不止有js,还有css和各类静态资源,webpack提供了各类loader来处理css和less、sass。vue-cli
转载一个关于webpack诞生的故事:express
2012年,一个叫作Tobias的,在Newberg(美国一个城市)读master的德国人要写一片学位论文。他以前是写c#的,历来没有写过一个web界面。他在一些特定的场景须要用到Google Web Toolkit中的一个叫作code splitting的功能。而在他的论文中他须要写一个web app,他就想找一个包含这个功能的库来用。他找到的这个库叫webmake,这也是一个bundler。可是却没有code splitting这个功能,因而他提了一个issue,而且写了一堆如何实现这个功能的代码,但愿维护者可以加入这个功能。在一番讨论事后维护者拒绝了他,因而在通过赞成以后,他把这个库fork到了了过去并本身加上了这个功能,给新的库取名为webpack。npm
2014年,Dan Abramov在Stack Overflow上提了一个关于hot module replacement的问题,Tobias用很大的篇幅给他介绍了这个还在开发的功能,详细解释了这个功能怎么在webpack里工做的,以及这个功能有多棒,你能够不用刷新浏览器了!
2015年,这时在Instagram工做的Pete Hunt经过一次演讲告诉了世界他们是如何使用webpack打包发布他们的react app的。而后你懂得,webpack就火了。像Facebook这样的公司也开始使用webpack了。可是其实Tobias只是每周大概花5 6个小时在webpack中。
是的,在这两个讨论中,webpack完全火了,走向了世界。
建立一个项目目录并生成 package.json。npm 使用它来管理项目依赖项。如下是基本命令:
mkdir webpack-demo
cd webpack-demo npm init -y
复制代码
npm install webpack webpack-cli --save-dev
复制代码
在src目录下新建一个index.js
console.log(111)
复制代码
执行命令:
webpack
复制代码
自动会生成一个dist文件夹,main.js里面会生成一个
console.log(111)
复制代码
能够借助html-webpack-plugin来新建一个HTML文件在浏览器看效果
npm install html-webpack-plugin --save-dev
复制代码
新建一个webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
plugins: [
new HtmlWebpackPlugin({
title: 'Webpack demo'
})
]
}
复制代码
修改index.js
document.write('你好世界!!!')
复制代码
执行命令:webpack,会看到dist文件下会多出来一个index.html,在浏览器打开index.html就出现熟悉的页面了
WDS 是在内存中运行的开发服务器,这意味着打包内容不会写入文件而是存储在内存中。这一区别在调试代码和样式时很是重要。
默认状况下,WDS 会在您开发应用程序时自动在浏览器中刷新内容,所以您无需亲自执行此操做。但它也支持高级 Webpack 功能——热模块更换(HMR)。
npm install webpack-dev-server --save-dev
复制代码
咱们须要用npm script来启动他,按照npm的约定,咱们定义一个命令,在package.json文件里面:
"scripts": {
"start": "webpack-dev-server --mode development",
"build": "webpack --mode production"
},
复制代码
这确定是很是眼熟了,咱们在使用vue-cli的时候必定会有相似的命令
正常状况下,输入命令npm start或者npm run start就能够启动项目了
可是通常状况下都会报这个错,由于webpack和WDS对于版本的兼容性要求很高,这一点也很是的恶心
个人解决方案是在package.json文件里面:
"webpack": "^4.17.1",
"webpack-cli": "^3.3.9",
"webpack-dev-server": "^3.8.2"
复制代码
而后从新npm install,再次启动项目就行了
若是你尝试修改代码,你应该会在终端里看到一些输出信息。浏览器也会根据变更作一些强制更新。
webpack.config.js
devServer: {
// 仅显示错误级别的输出,从而减小输出信息
stats: "errors-only",
// 从环境变量中传入 host 和 port,从而达到可配置
//
// 若是你使用 Docker, Vagrant 或者 Cloud9, 那么把
// host 设置为 "0.0.0.0";
//
// 0.0.0.0 对于全部的网络设备都是可用的
// 而默认的 `localhost` 不行.
host: process.env.HOST, // 默认为 `localhost`
port: process.env.PORT, // 默认为 8080
open: true, // 在浏览器中打开
},
复制代码
webpack.config.js
host: '0.0.0.0',
复制代码
package.json
"start": "webpack-dev-server --host 0.0.0.0 --mode development",
复制代码
此时启动之后就能够用过本机IP地址访问本地服务了
当打包文件发生变化时,开发服务器会自动重启;可是,当 Webpack 配置变化了呢?若是说,每次配置变更你就要手动重启开发服务器,没过一下子,你就会厌烦不堪了。如 GitHub 中所讨论的那样,咱们可使用 nodemon 监视工具自动执行该过程。
安装nodemon
npm install nodemon --save-dev
复制代码
package.json
"start": "nodemon --watch webpack.config.js --host 0.0.0.0 --exec \"webpack-dev-server --mode development\"",
复制代码
这个选项适合有时候热更新无论用了,能够试一下这个选项,基本都能解决
devServer: {
watchOptions: {
// 首次更改后延迟多少时间再从新构建
aggregateTimeout: 300,
// 轮询的时间间隔 (单位 ms, 接受 Boolean 类型的值)
poll: 1000,
},
},
复制代码
webpack-dev-middleware是一个包装程序,它将经过webpack处理的文件发送到服务器。它在webpack-dev-server内部使用,可是若是须要,它能够做为单独的软件包使用,以容许进行更多自定义设置。咱们将看一个webpack-dev-middleware与Express服务器结合的示例。
npm install --save-dev express webpack-dev-middleware
复制代码
module.exports = {
devServer: {
// 仅显示错误级别的输出,从而减小输出信息
stats: "errors-only",
// 从环境变量中传入 host 和 port,从而达到可配置
//
// 若是你使用 Docker, Vagrant 或者 Cloud9, 那么把
// host 设置为 "0.0.0.0";
//
// 0.0.0.0 对于全部的网络设备都是可用的
// 而默认的 `localhost` 不行.
host: '0.0.0.0', // 默认为 `localhost`
port: process.env.PORT, // 默认为 8080
useLocalIp: true,
open: false, // 在浏览器中打开
watchOptions: {
// 首次更改后延迟多少时间再从新构建
aggregateTimeout: 300,
// 轮询的时间间隔 (单位 ms, 接受 Boolean 类型的值)
poll: 1000,
},
},
output: {
publicPath: '/',
},
plugins: [
new HtmlWebpackPlugin({
title: 'Webpack demo'
})
]
}
复制代码
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);
// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
app.use(
webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath,
})
);
// Serve the files on port 3000.
app.listen(3000, function () {
console.log('Example app listening on port 3000!\n');
});
复制代码
"scripts": {
"start": "nodemon --watch webpack.config.js --host 0.0.0.0 --exec \"webpack-dev-server --mode development\"",
"build": "webpack --mode production",
"server": "node server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
复制代码
npm run server
复制代码
在localhost:3000就能够看到输出的服务了
webpack内容很是多,接下来还会继续记录loader和分包加载以及各类插件