Starter
Webpack is a front-end build systems like Grunt and Gulp.It can be used as a module bundler similar to Browserify, and do much more.
A module bundler 模块打包工具(打包成较小/少的文件) Module:can be CommonJS,AMD,ES6 modules,images,json,coffeescript,less,...and custom stuff. 任何一个静态的资源都可以视为一个module,被引用;还可整合第三方的类库,也视为module,在项目中引用
特性:
- code spliting :代码分割,只加载需要的文件(切分依赖树,分到不同代码块,然后按需加载这些依赖,减少初始化时间,类似懒加载)
- loader :各module通过对应的loader处理
- plugin system :插件系统,eg:模块热更新
安装:
npm install webpack -g
Hello World
hello.js
require('./world.js'); // CommonJS模块化方式 /* 1. style-loader 对css-loader处理完的文件通过<style>标签插入html 2. css-loader 使得webpack可以处理.css文件 3. 或者直接 require('./style.css'),执行webpack命令时使用module-bind eg: webpack hello.js hello.boundle.js --module-bind 'css=style-loader!css-loader' */ require('style-loader!css-loader!./style.css'); function hello(str){ alert(str); } hello("Hello world"); // 执行
world.js
function world(){ return {}; }
style.css
html,body{ padding: 0; margin: 0; } body{ background:#eee; }
执行
> npm install css-loader style-loader --save-dev > webpack hello.js hello.boundle.js # 若直接 require('./style.css'),执行webpack命令时使用module-bind > webpack hello.js hello.boundle.js --module-bind 'css=style-loader!css-loader' --watch
--watch
文件改变时自动更新打包--progress
显示打包过程--display-modules
列出打包的模块--display-reasons
列出打包模块的原因
使用打包的js:index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>webpack test</title> </head> <body> <script type="text/javascript" src="hello.boundle.js"/> </body> </html>
webpack.config.js
webpack配置文件, Refer Configuration
src/script/main.js
function hello(){ alert("Hello world"); }
index.html
<script type="text/javascript" src="dist/js/boundle.js"/>
webpack.config.js
module.exports={ entry:'./src/script/main.js' // 打包入口 ,output:{ // 打包结果文件 path:'./dist/js' filename:'boundle.js' } }
执行
# 默认会使用webpack.config.js > webpack # 可使用--config指定webpack配置文件 > mv webpack.config.js webpack.dev.config.js > webpack --config webpack.dev.config.js
- 注:可通过npm执行webpack,配置package.json (customize scripts field):
"scripts":{ ... "webpack":"webpack --config webpack.dev.config.js --progress --display-module --colors" }
# 执行 > npm run webpack
- 注:可通过npm执行webpack,配置package.json (customize scripts field):
输入和输出配置 ( entry & output) :
entry: which Webpack reads to build,could for SPA-one entry point,MPA-multiple entry points
- SPA: string
- MPA: array,json (多个chunk)
output:
- filename: 可使用占位符 (eg:
[name]
,[hash]
,[chunkhash]
-可用于版本管理),防止multiple entry输出相互覆盖
- filename: 可使用占位符 (eg:
Demo webpack.config.js:
module.exports={ // entry:'./src/script/main.js' // 打包入口 // entry:['./src/script/main.js','./src/script/a.js'] entry:{ main: './src/script/main.js' page1: ['./src/script/a.js','./src/script/b.js'] page2: './src/script/c.js' }, output:{ // 打包结果文件 path:'./dist/js' //filename:'boundle.js' filename:'[name]-[chunkhash].js' //chunkhash md5 文件改变后会变化 } }
Plugin
html-webpack-plugin
Demo:自动化生成html页面
安装html-webpack-plugin插件
> npm install html-webpack-plugin --save-dev
配置插件使用(webpack.config.js)
var htmlWebpackPlugin = require('html-webpack-plugin'); module.exports={ entry:{ main: './src/script/main.js' page1: ['./src/script/a.js','./src/script/b.js'] page2: './src/script/c.js' } ,output:{ path:'./dist', filename:'js/[name]-[chunkhash].js', publicPath:'http://cdn.com/' } ,plugins:[ new htmlWebpackPlugin({ template: 'index.html', filename: 'index.html', // output html inject: 'head', // 指定脚本放入的位置,eg: head,body,..,false minify:{ // 最小化html removeComments:true, collapseWhitespace:true }, chunks:['main','page1'], // 可通过chunks/excludeChunks限定引用 date: new Date() }) ] }
template: index.html (支持EJS模版语言,可获取config中的配置)
<%= htmlWebpackPlugin.options.date %> //在html中添加引用生成的js <% for(var key in htmlWebpackPlugin.files){%> <%=key%>:<%= JSON.stringfy(htmlWebpackPlugin.files[key])%> <% } %> <%=htmlWebpackPlugin.files.chunks.main.entry%> <%=htmlWebpackPlugin.files.chunks.page1.entry%>
inline直接内嵌js code, 修改template: index.html
<script type="text/javascript> <% compilation.assets[htmlWebpackPlugin.files.chunks.main.entry.substr(htmlWebpackPlugin.files.publicPath.length)].source() %> </script>
Loaders
编译资源文件的预加载器。在webpack.config.js
中,module.loaders
领域被用于设定加载器。 注意:处理方式从右到左! Refer Loader
babel-loader
Demo: 使用babel-loader转换ES6语法的代码为浏览器直接可以接受的JS代码
安装依赖
npm install babel-loader babel-core --save-dev npm install babel-preset-latest --save-dev
webpack.config.js
var path=require('path'); module.exports={ ... module:{ loaders:[ { test:/\.js$/, exclude:path.resolve(__dirname,"node_module"), include:path.resolve(__dirname,'src'), loader:'babel', query:{presets:['latest']} } // exclude/include condition 需使用绝对路径 // babel参数,例如presets,也可以在.babelrc或package.json中指定 ] } }
注: 上面babel参数,例如presets,也可以在.babelrc或package.json中指定
.babelrc
{ presets:['latests'] }
package.json
{ ... "babel":{ "presets":["latest"] } ... }
css-loader & style-loader
安装
npm install style-loader css-loader --save-dev
webpack.config.js
module.export={ ... module:{ loaders:[ {...}, { test:/\.css$/, loader:'style-loader!css-loader' } ] } ... }
postcss-loader
安装
npm install postcss-loader --save-devnpm install autoprefixer --save-dev
webpack.config.js
module.exports={ ... module:{ loaders:[ {...}, { test:/\.css$/, loader:'style-loader!css-loader?importLoaders=1!postcss-loader' } //发现生成的css中,@import的css部分未有postcss,需在css-loader加入importLoaders参数,表示css-loader引入它之后n个loader,这里即引入postcss-loader处理 ] }, postcss:[ require('autoprefix')({ broswers:['last 5 versions'] }) ] ... }
注:特殊css,有些浏览器可能不支持,或语法不同,需加入浏览器前缀,引入postcss-loader处理,eg:
.flex-div{ display:flex; }
less-loader/sass-loader
npm install less less-loader --save-dev
# npm install sass-loader --save-dev
webpack.config.js:
module.exports={
...
module:{
loaders:[
{...},
{
test:/\.less$/,
loader:'style!css!postcss!less'
},
// 使用less-loader,可以不给css-loader加入importLoaders,也可使@import的less被postcss处理
{
test:/\.sass$/,
loader:'style!css!postcss!sass'
}
]
}
...
}
html-loader/ejs-loader
处理模版文件 templating loader,eg: html-loader,ejs-loader,jsx(already include in babel)
- 方式一:当作一个字符串处理,eg: html-loader 将HMTL模板文件当做一个string输出
- 方式二:当成一个已经编译好的模版函数,eg:将EJS模板文件当做一个函数输出
注:jsx-loader已被集成到babel工具中,不需要单独安装引入
安装loader
npm install html-loader --save-dev npm install ejs-loader --save-dev
webpack.config.js:
module.exports={ ... module:{ loaders:[ {...}, { test:/\.html$/, loader:'html-loader' }, { test:/\.ejs$/, loader:'ejs-loader' } ] } ... }
template: layer.ejs:
<div> <div> This is <%=name%> layer</div> </div>
执行webpack,会生成layer.js
在app.js中使用: 实现index.html的app节点下下插入模板layer
import './css/common.css'; import Layer from './components/layer/layer.js' const App=function(){ var dom=document.getElementById('app'); var layer=new Layer(); dom.innerHTML=layer.tpl({ name:'Tom' }); } new App();
file-loader
文件处理
安装file-loader
npm install file-loader --save-dev
webpack.config.js, loader:
{ test:/\.(png|jpg|gif|svg)$/i, loader:'file-loader', query:{ path:'assets/[name]-[hash:5].[ext]' } }
注:css/less/html 中引入相对路径的图片都没有问题,会自动替换,但在template文件中,需如下(使用require命令)
<img src="${require('../../assets/bg.png')}" />
url-loader
可设置limit
- 当文件或图片超过limit,会转换成一个正常的URL引用,eg:
<img src="4853ca667a2b8b8844eb2693ac1b2578.png">
- 当小于limit,会生成base64编码的可直接嵌入的数据,eg:
<img src="data:image/png;base64,iVBOR...uQmCC">
npm install url-loader --save-dev
webpack.config.js, loader:
{
test:/\.(png|jpg|gif|svg)$/i,
loader:'url-loader',
query:{
limit:20000, // 20k
path:'assets/[name]-[hash:5].[ext]'
}
}
image-webpack-loader
可以压缩图片
npm install image-webpack-loader --save-dev
{
test:/\.(png|jpg|gif|svg)$/i,
loader:[
'url-loader?limit=20000&name=assets/[name]-[hash:5].[ext]',
'image-webpack'
]
// 处理顺序一样是从右到左,先image loader再url loader
}
优化
- 开启调试 SourceMap
- ESLint 检查代码格式
- 区分开发环境 和 生产环境
- 使用 middleware 来搭建开发环境
- Webpack Dev Server,本地 rewrite 规则
- 代理远程接口
- 模块热更新
- Webpack Watch Mode
webpack-dev-server
一个小型的Node Express服务器,为通过wepack打包生成的资源文件提供web服务 功能:
- 搭建本地服务器
- 自动刷新
安装:
npm install webpack-dev-server -g
使用: 使用:
> webpack-dev-server
//或启动热加载
> webpack-dev-server --hot --inline