什么是Webpack
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。
Webpack的工作方式是:
把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。
webpack 特点
代码拆分
Webpack 有两种组织模块依赖的方式,同步和异步。异步依赖作为分割点,形成一个新的块。在优化了依赖树后,每一个异步区块都作为一个文件被打包。
Loader
Webpack 本身只能处理原生的 JavaScript 模块,但是 loader 转换器可以将各种类型的资源转换成 JavaScript 模块。这样,任何资源都可以成为 Webpack 可以处理的模块。
智能解析
Webpack 有一个智能解析器,几乎可以处理任何第三方库,无论它们的模块形式是 CommonJS、AMD 还是普通的 JS 文件。甚至在加载依赖的时候,允许使用动态表达式 require("./templates/" + name + ".jade")。
插件系统
Webpack 还有一个功能丰富的插件系统。大多数内容功能都是基于这个插件系统运行的,还可以开发和使用开源的 Webpack 插件,来满足各式各样的需求。
快速运行
Webpack 使用异步 I/O 和多级缓存提高运行效率,这使得 Webpack 能够以令人难以置信的速度快速增量编译。
总结下来其主要的优势:
1.按需加载模块,按需进行懒加载,在实际用到某些模块的时候再增量更新
2.webpack 是以 commonJS 的形式来书写脚本,但对AMD/CMD 的支持也很全面,方便旧项目进行代码迁移。
3.能被模块化的不仅仅是 JS 了,能处理各种类型的资源。
4.开发便捷,能替代部分 grunt/gulp的工作,比如打包、压缩混淆、图片转base64等。
5.扩展性强,插件机制完善
安装
建立一个新文件夹,此处命名webpack-demo3,进入此文件夹开始安装
首先要全局安装:
npm install webpack -g
webpack -h查看相关指令
初始化npm说明文件 package.json:
npm init
安装到项目目录:
npminstall webpack --save-dev
安装成功后,出现node-modules文件夹
使用
简单打包,创建一个hello.js文件,打包成boundle.js
webpack hello.js boundle.js (直接webpack)
下面是打包过程中一些常用的参数:
css文件 :webpack hello.jsbundle.js --module-bind "css=style-loader!css-loader"
--module-bind :绑定类型
--watch:以监听改变,自动更新。
--progress :可以看到文件打包的过程。
--display-modules :将罗列所有引用的模块及相应模块的处理方式
mkdir filename :新建文件夹
webpack --config webpack.dev.config.js 指定配置文件
正式开始:
首先创建两个文件夹 src 和dist, src文件夹用来存放原始数据和我们将写的JavaScript模块,dist文件夹用来存放之后供浏览器读取的文件(包括使用webpack打包生成的js文件以及一个index.html
文件)
Src 文件夹下面创建3个文件夹comments、css、images,分别用来存放要打包的各种文件,公共的css文件,图片文件,还有一个app.js作为唯一的入口文件
然后在根目录下要新建两个文件,index.html(html模板文件)和webpack.config.js(配置文件)
最后在package.json 中的script 下添加参数 "webpack":"webpack --configwebpack.config.js --progress --display-modules --display-reasons --colors"
这时候就可以使用 npm run webpack 进行打包了。
入口文件 app.js:
html模板文件:
下面是webpack.config.js文件:
var HtmlWebpackPlugin=require('html-webpack-plugin');
var path=require('path');//2.0以后的版本需要引入这个模块
module.exports={
entry:'./src/app.js',
output:{
path:path.resolve(__dirname, './dist'),//两个下划线
filename:'js/[name].bundle.js'
},
module: {
rules: [
//处理ES6
{
test: /\.js$/,
use: [
{
loader:'babel-loader',
options:{
presets:['env'] //可以在package.json中指定
}
}
],
//exclude:__dirname+'./node_modules/',//排除特定条件 绝对路径
//include:__dirname+'./src/' //匹配特定选项
exclude:path.resolve(__dirname+'node_modules'),
include:path.resolve(__dirname+'src')
},
//处理html文件
{
test:/\.html$/,
loader:'html-loader'
},
//处理模板文件
{
test:/\.tpl$/,
loader:'ejs-loader'
},
//处理图片文件
{
test:/\.(png|jpg|gif|svg)$/i,
//loader:'file-loader'
loader:'url-loader',
options:{
limit:20000,
name:'images/[name]-[hash:5].[ext]'
}
},
//处理项目中的css文件
/* {
test:/\.css$/,
//loader:'style-loader!css-loader!postcss-loader'
use:[
'style-loader',
{
loader:'css-loader',
options:{
importLoaders:1 //指定后面的loader数量 来处理imort进来的资源
}
},
{
loader:'postcss-loader',
options:{
plugins:[
require('postcss-import')(),//添加引用@import的翻译
require('autoprefixer')({ //自动添加css前缀
browsers:['last 5 versions'] //最近的5个浏览器版本
})
]
}
}
]},*/
//处理sass|css|less文件 综合写法
{
test:/\.(scss|css)$/,
use:[
'style-loader',
'css-loader',
/*{
loader:'css-loader',
options:{
importLoaders: //指定后面的loader数量 来处理imort进来的资源
}
},*/
{
loader:'postcss-loader',
options:{
plugins:[
require('postcss-import')(),//添加引用@import的翻译
require('autoprefixer')({ //自动添加css前缀
browsers:['last 5 versions'] //最近的5个浏览器版本
})
]
}
},
//'less-loader',
'sass-loader'
]},
//处理less文件
/* {
test:/\.less$/,
loader:'style-loader!css-loader!postcss-loader!less-loader'
}*/
]
},
//自定义生成HTML文件
plugins:[
new HtmlWebpackPlugin({
filename:'index.html',//文件名
template:'index.html',//以文件原有的模板为基础
inject:'body',//inject :true | ‘head’ | ‘body’ | false 注入的位置
})
]
}
constpath=require('path');//2.0以后的版本需要引入这个模块
entry : string 单独入口 | object多个入口多个文件 |array数组多个文件打包成一个文件
output:
path:打包后的地址
filename:文件名(在多个入口打包成多个文件是需要利用占位符)
[name]:模块名称、[chunkhash]:chunk内容的hash、[hash]:模块标识符的hash
接下来是配置说明:
1. 用来自定义生成html页面:
安装插件: $ npm installhtml-webpack-plugin --save-dev
html-webpack-plugin:配置
title : 用于生成的HTML文件的标题。
filename : 用于生成的HTML文件的名称,默认是index.html。你可以在这里指定子目录(例如:assets/admin.html)
template : 模板的路径。支持加载器,例如html!./index.html。
inject :true | ‘head’ | ‘body’ | false 。把所有产出文件注入到给定的 template 或templateContent。当传入 true或者‘body’时所有javascript资源将被放置在body元素的底部,“head”则会放在head元素内。
favicon : 给定的图标路径,可将其添加到输出html中。
minify : {…} | false 。传一个html-minifier配置object来压缩输出。
hash : true | false。如果是true,会给所有包含的script和css添加一个唯一的webpack编译hash值。这对于缓存清除非常有用。
cache : true | false 。如果传入true(默认),只有在文件变化时才 发送(emit)文件。
showErrors : true | false 。如果传入true(默认),错误信息将写入html页面。
chunks : 只允许你添加chunks [] 。(例如:只有单元测试块 )
chunksSortMode : 在chunk被插入到html之前,你可以控制它们的排序。允许的值 ‘none’ | ‘auto’ | ‘dependency’ |{function} 默认为‘auto’.
excludeChunks : 允许你跳过一些chunks(例如,不要单元测试的chunk).
xhtml : 用于生成的HTML文件的标题。
title : true | false。如果是true,把link标签渲染为自闭合标签,XHTML要这么干的。默认false。
html模板中
遍历参数:
<% for (var key in htmlWebpackPlugin.files){%>
<%= key %>:<%=JSON.stringify(htmlWebpackPlugin.files[key])%>
<%}%>
<%for (var key in htmlWebpackPlugin.options){%>
<%= key %>:<%=JSON.stringify(htmlWebpackPlugin.options[key])%>
<%}%>
直接引入脚本文件:
<script type=’text/javascript’ src='<%= htmlWebpackPlugin.files.chunks.a.entry %>'></script>
内联引入脚本文件:
<%=compilation.assets[htmlWebpackPlugin.files.chunks.main.entry.substr(htmlWebpackPlugin.files.publicPath.length)].source()%>
将除了公共文件的其他脚本以外联的形式引入:
<%for(var k in htmlWebpackPlugin.files.chunks){ %>
<% if(k !=="main"){ %>
<script type='text/javascript'src='<%=htmlWebpackPlugin.files.chunks[k].entry %>'></script>
<% } %>
<%} %>
2. 用babel-loader转换ES6
babeljs.io官网:http://babeljs.io/docs/plugins/
1.安装方法 npm installbabel-loader babel-core babel-preset-env webpack --save-dev
2.所以后面的参数'由presets:['latest']相对于的变成了presets: ['env']
3.官方并没有废弃query 也没有指明options是新参数 实际测试两种方法都可以 生成结果也一模一样
4.loader: 'babel-loader'才能被识别
5.include和exclude需要绝对路径,所以include:__dirname+'./src/' 加前缀__dirname
配置(推荐):在 webpack.config.js 文件中指定 loader。
举例:
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: true
}
}
],
exclude:__dirname+'./node_modules/',//排除特定条件 相对路径
include:__dirname+'./src/'//匹配特定选项
}
]
}
内联:在每个 import 语句中显式指定 loader。 import Styles from 'style-loader!css-loader?modules!./styles.css';
CLI:在 shell 命令中指定它们。webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'
3. 处理项目中的css|less|sass文件:
安装失败的情况下需要先全局安装 -g
需要安装的loader: css-loader、style-loader、sass-loader和node-sass、less-loader和less-loader :
postcss : css文件预处理: npm install postcss-loader --save-dev
自动加前缀:autoprefixer插件 npm install autoprefixer --save-dev
4. 处理项目中的模板文件:
1. 安装 : html-loader : npm install html-loader --save-dev
2. 安装:ejs-loader : npm install ejs-loader --save-dev
5. 处理项目中的图片以及其他文件:
1.安装file-loader : npm install file-loader --save-dev
2.安装url-loader : npm install url-loader --save-dev
配置文件
{
test:/\.(png|jpg|gif|svg)$/i,
//loader:'file-loader'
loader:'url-loader',
options:{
limit:20000,
name:'images/[name]-[hash:5].[ext]'
}
}
三种类型的图片:
1. css文件中 2.html文件中<img src=''> 3.模板文件中:需要特殊处理 <img src="${require('../../images/top_ico.png') }">