可以结合慕课网的视频来读这篇文章,地址:http://www.imooc.com/learn/802
Webpack简介:
给JS准备的一个打包工具,可以把很多的模块打包成很好的静态,且有一个自己的特性叫做代码分割 ,webpack有个整个loader的概念,通过loader可以处理各种各样的文件,可处理css common.js 图片文件 AMD less文件 es6 自定义文件如:vue文件等。
官方的定义:它是一个模块的打包器。
大概的处理过程:左边 .css .js .png 等都视为一个模块通过箭头之间有依赖关系的模块群之后webpack会对依赖的模块群进行处理把它打包成浏览器可以直接运行的JS文件和CSS文件还有真实的图片
Webpack的最大特点是代码分割;
代码分割:在项目中只是加载当时只需要的那部分文件;
####### Webpack的目标:
- 切分它的依赖数,会把它的依赖数切分到不同的代码块里,然后按需
加载这些代码块(类似于懒加载概念) - 为了保持初始化的加载时间更少
- 任何一个静态的资源都是被视为一个模块,在项目中被引用(在开发过程中有很多的便利)
- 它可以整合一些第三方的类库,并且把第三方类库也视为一个模块,并在项目中引用
- 打包的过程中可以自定义,几乎每一个部分都可以自定义,做一些自己想做的事情,非常适合大型项目
Webpack和其他打包工具的不同:
- code Spliting 代码分割
- loaders
- 模块热更新(在开发过程中大大提高的调试和效率)
webpack 安装
进入目录 cd xxx
建立一个文件夹 如:mkdir webpack-text
进入文件的 cd wabpack-text
在文件下初始化 npm init
全局安装webpack:npm install webpack -g
初始化完之后装webk:npm install webpack --save-dev
安装完之后可以看见项目下有 package.json和一个node_modules的一个文件,安装完之后用编译器打开当前目录,就可以创建开始编码了,写好了之后,就可以在命令中输入如:
Webpack hello.js hello.bundle.js webpack直接跟文件的名称后面再去跟打包后的名称
这就完成一次简单的打包操作
操作成功之后它会给我们一部分值(在命令行中可以看到以下参数):
- 哈希值 webpack版本
- 这次打包花费的时间
- Asset 显示这次打包生成的文件
- size这次打包文件的大小
- Chunks 这次打包的分块
- chunk Names 这次打包的块名称
Webbpack 支持三种的模块化方式AMD commonjs es6的模块化
安装好之后还要指定相应的loader 才可以引入如:require(‘css-loader!./style.css’) 加上之后就可以执行了
要是引入的css生效还需要借助 style-loader! 如:require(‘style-loader!css-loader!./syle.css’)
很多人就有了疑问,我每次都得加这么多loader么?那不是很麻烦
对引入的css的文件,还有一种处理方式:在命令行输入 :
Webpack hello.js hello.bund --module-bind’css=style-loader!css-loader’ 这个方法也很麻烦,每次文件改变都得输入这个命令,下面是更简便方法,文件改变打包的文件也自动更新、自动打包。
对于以上两种方法也和繁琐可以通过文件自动打包,自动更新 如:Webpack hello.js hello.bund --module-bind’css=style-loader!css-loader’ --watch
Webpack 还有可以看到打包的过程的方法 : 右下可以看到百分比读条(右下可以看到短暂的百分比读条)
Webpack hello.js hello.bund --module-bind’css=style-loader!css-loader’ --progress
webpack的基本配置以及webpack配置里面的一些参数的功能
webpack 的配置文件 在webpack下建立一个 webpack.config.js 的文件 为什么要这样建立配置文件:
如果直接使用webpack这个命令的话,webpack会在根目录下寻找webpack.config.js 把它作为默认的配置取运行
配置文件的最基础的配置
module.exports = {
entry: ‘./src/srcipt/main.js’, //表示配置入口
output: {
path: ‘./dist/js’, //指明打包以后的文件放到什么地方
filename: ‘bundle.js’ //打包以后的文件名
}
}
配置好之后直接在命令行输入 webpack 就可以执行了
若给配置改个名的处理方法 如 配置不叫 webpack.config.js 而是 webpack.dev.config.js
可以通过命令行来通过webpack的参数config来指定 如:
Webpack --config webpack.dev.config.js 这样就生效了
在有配置的情况下怎么加参数 :
可以配合npm的脚本 package.json 中的 “scripts”中定义一段脚本 :
“webpack”: “Webpack --config webpack.config.js --progress --display-module --colors”
在脚本中定义好之后就可以在命令行中输入:
npm run webpack 脚本就可以运行了
数组的方式:入口文件放到数组里面
module.exports = {
entry: [‘./src/srcipt/main.js’,’./src/script/a.js’], //表示配置入口 处理文件多的话另一种写法
output: {
path: ‘./dist/js’, //指明打包以后的文件放到什么地方
filename: ‘bundle.js’ //打包以后的文件名
}
}
#######entry是对象的方式
注意:文件上面的哈希值互相不一样了,可以认为是文件的版本号,也可以认为是MD5值(MD5算法就是为了保证每个文件的唯一性),也就是说只有当这个文件发生改变的时候,这个哈希值才会变化,这个特点,在我们的项目中对静态资源版本号的管理是非常有用的,平时我们项目中上线的时候,正好需要只上线那些已经被我们改过的文件
生成项目中的的html页面文件
就想上面对象为入口的话,它的文件名是[name]是不确定的,难道每一次这种打包都要手动去设置路径吗,那岂不是非常麻烦:用webpack的插件来解决这个问题
先用npm install html-webpack-plugin --save-dev
好了之后去webpack的配置文件webpack.confing.js中
但是上面有一个弊端就是插件生成的index.html文件是在js中,而在我们自定义的index.html之间没有建立任何的联系,这是不满足项目的需求的,下图
解决方法:在配置文件的plugins 的初始化对象传参(这是为了让咱们自定义的index.html和文件中生成的index.html建立联系)
把生成号的html放到dist中而js需要放到js的文件中,在配置中如下操作:
Plugins 还有什么参数呢,还可以指定我们生成的名称(filename),还有我们可以直接指定想吧我们的脚本放在头部还是body标签里面,如下图:
通过上两幅图的方法就可以取到在plugin中设置title的值
通过上面两个获取data的值
上两个图是对htmlWebpackPlugins下files和options 属性中插件参数的遍历
上两个图就是output中的pulicPath就是设置上线时候的前面的网址
注:[ www.npmjs.com中搜html-webpackplugin( http://www.npmjs.comhtml-webpack-plugin) 可以看到webpack中的插件的使用和说明
Webpack插件的多页面应用
根据不同的页面可以指定不同的模块(或者根据不同的页面指定相同的模板),不下图:
注:如果用chunks或excludeChunks来引入模块的话,index.html 里面不能有任何注释,否则会疯狂报错
把配置里面的inject:‘body’ 自动引入发到body里面,chunks只加载需要的块就可以了
上面的这种方法需要一一去对应,就显得非常的麻烦,所有就提供了另外一个参数(excludeChunks[除了那个都是要加载的])
再往下深入一点,如果我们要把页面的性能达到极致的话,吧初始化的脚本直接嵌入到页面,而不以链接的形式引入在页面,如下图就是以链接形式引入页面的,这种方式会增加http请求
上图是githup里面webpack的初始haul的脚本直接嵌入到页面的方法
有同学会想到既然我们webpack这个配置文件中运行js,那我们为什么不调用nodejs的读取文件的API直接读取我们想要引入进来的文件呢
但是会有一个问题,就是直接引入这个文件,不会经过webpack处理的,而你想要引用这个经过webpack流处理过后的文件,通过这种方式你是做不到的。
那么通过什么方式能做到呢,通过compilation(webpack它自身暴露出来的给我们可以使用的一个引用)
上两图的操作就可以直接拿到不带publicPath 的路径,若htmlWebpackPlugin.files.chunks.main.entry 只是这样写,没有后面的substr(..)的话,获取到的还是带有publicPath的路径,之后就可以如下图中的方法取到它里面的内容:
上图公用的是上面的红圈部分是直接嵌入页面,而下面的a、b、c是引入进来的。
总结webpack中plugin的内容:首先讲到了如何使我们的html和我们的动态的生成的文件名称一一对应上,然后我们探查了一下这个htmlWebpackPlugin究竟通过它能够怎么样的自定义我们的这个html,并且可以通过模块,还有它里面的一些参数,如何传参;之后我们一起学习了多页面的时候,如何通过htmlWebpackPlugin来生成多个html,最后我们一起深入的探究了一下怎么通过htmlWebpackPlugin并且结合模板的方式,去吧我们的生成的js里面的内容直接inline的形式引入到我们的html里面中
什么是Loader以及Loader的特性
#######loader的定义:
loader只是处理资源文件的,也就是说它接受资源文件为一个参数,然后它处理完了之后会返回一个新的资源,这么一个过程就是loader的处理。比如说你用 了loader,就可以告诉webpack处理的这个CoffeScript或者是JSX的时候去使用loader,就可以处理这两种webpack不支持的这两种格式。
#######Loader的特性:
- 可以是被串联的 如:之前的 css-loader!style-loader! 这种串联的方式去使用loader
- 可以是同步也可以是异步的
- 可以在nodejs环境下去运行
- 可以接受一些参数
- 可通过正则表达式,指定的后缀名,在这个配置中就可指定这个某一个后缀名的文件有某个loader来执行(这是一个它的特点)
- loader可以通过npm来安装 npm install
- loader可以获取configuration (也就是webpack的配置)
- 我们的插件可以给loader更多的特性
- loader还可以生产额外的文件(除了处理我们指定的文件之外,loader还可以生产额外的文件)
#######使用loader的方式有三种:
- 在require中就可以指定指定这个loader 如[ require( “./loader! ./dir/file.txt” ) ] [ require( “ !style!css!less!bootstrap/less/bootstap.lesss ” ) ]
- 这配置在我们的配置文件
- 直接使用CLI(在命令行中 webpack --module-bind jade --module-bind ‘css=style!css’)
三种方式的的第一种和第三种都用过了,这个用第二种在配置文件的使用:
[ http://babeljs.io/docs/setup/#installation(http://babeljs.io/docs/setup/#installation) 点击Build systems中的webpack 可以看到:
通常之后我们还的给它一个配置 {
“presets”: [ “es2015” ]
// babel 也有自己的的插件都在更新和落实,给各个浏览器支持,不断的发布草案,不断的修订
//我们可以通过指定presets来告诉我们 这个babel-loader 知道来转换某一些特性,为我们的js,若这个时候你需要它转换为所有的特性,直接指定latest(包括es2015,es2016,es2017)
}
//指定presets其实就是告诉babel-loader 怎么去处理这个我们这些的js,给不同的特性,我们需要转换哪个个特性
那么怎么去指定这个插件,涉及到之前说的参数的问题,直接loader 指定一个参数如下两图:
注:指定完之后还的安装这个插件:
也可以通过上图的方式来指定presets,这样我们就不用再我们的配置文件中指定了
注意:在配置中loader:’babel’这样写是会报错的,调好好久,一点不要省略babel后面的loader(之前webpack1.x的时候可以省略,但是webpack2.0就不可以省略)
打包的时间长,原因在loader上,因为babel-loader是非常耗时的转换,那么如何去改善呢
Loaders定义的参数有五个 exclude 排除范围 (如:某一目录下不让去处理)【一些打包过后的文件不希望去处理】如下图:
include 指定包含的范围
loaders可以把一长串的loader一个数组表示
注意:Webpack中的Using Loaders只说了一些简单的定义如何去使用,真正的文档是在 Configuration
用了exclude 之后吧已经打包好的文件排除了,不进行二次打包之后,执行效果很快
Condition可以是一个正则表达式,也可以是一个字符串(包含着绝对路径的),还可以是一个函数或者是包含着绝对路径的一个数组
总结:安装了babel之后,如何通过webpack的配置来使我们的webpack来处理es6中的代码,把es6代码转换成可以运行的es代码
处理项目中的css
安装style-loader 和css-loader
npm install style-loader css-loader --save-dev
引入完画红圈的部分,就可以在js中处理css文件了
flex布局兼容浏览器效果还不是很好,需要加前缀(手动加前缀太麻烦),webpack里面也有加前缀的loader 是:postcss-loader(它是一个后处理器)
先安装上npm install postcss-loader --save-dev
还需要安装 npm install autoprefixer --save-dev
在安装一个 npm install precss --save-dev
特别注意:上图是再创建一个新的postcss.config.js文件,里面写上上述内容
注:这一点webpac2.0 和webpack1.0也是有很大差别的
注:webpack2.0 之后从外部引入文件不用在里面loader里面加入importloader=1,可以直接执行postcss-loader了
webpack 处理less和sass
首先安装less-loader:npm install less-loader --save-dev 若没有安装less,先安装less:npm install less
之后在loaders数组里新增一个匹配规则:
loader 的处理方式是从右到左的,less-loader或sass-loader处理完了以后,再处理postcss-loader
Sass的处理和less的处理方式一样,也是在loaders里面新增一个匹配规则
处理项目中模板文件
可以看到项目中有一个模板layer.html,通常处理这种模板的文件的做法,是webpack把这个模板文当做字符串进行处理,还有就是把这个webpack当做已经编译好的一个处理函数
打开webpack的官网,可以看到左边有一个List of loaders,进入,右边有目录点击templating,之后就可以看到出到出来模板的相关loader都在这里列出来了
如上图在layer.js 中吧模板引入进来,.html文件是作为一个字符串进行处理
处理模块还需要安装 npm install html-loader --save-dev
安装好之后在loaders规则中加一个匹配规则
实际项目中,更复杂,需要用到模板语法;
假设模块是.ejs结尾的模板;
首先安装npm install ejs-loader --save-dev
如上图,layer.js 文件也的变动,图中当我们载入ejs模板的时候,webpack官网有说明,它会返回的是一个function,所以tpl它就不代表字符串了,它表示已经编译过的一个函数,那么函数时干什么用的呢,可以在app.js中传入我们所需要的数据,如下图:
Jsx表示react框架 用的非常广的一个loader,已经被寄生到了babel这个工具里面了,只需要一个写设置,就可以支持jsx
处理项目中图片文件以及其他文件
处理图片文件分几种情况:
第一种 css文件里面会有很多图片文件
第二种 模板里面直接引入某一张图片
第三种 最底部文件 index.html中对图片的引用
引入图片之后,先安装 npm install file-loader --save-dev
只有在loaders中增加对图片处理的规则
上面是指定第一种情况,在css中根据路径来打包图片文件
在index.html中直接引入图片一会直接被loaders匹配的设置好的规则处理好,显示在页面(第三种)
图片打包后的输入地址,想改变它的地址,从默认下放到dist的目录下,如果我们要改变它的话,给loader加一些参数
安装url-loader:npm install url-loader --save-dev
url-loader 其实和 file-loader 很类似,但是可以指定一个参数,limit这个参数,limit是当你的图片或者文件大小,大于了你指定的limit后,它就会直接丢给file-loader去处理,然而当你小于limit指定的大小限制的时候,它会把的文件或者图片转为base64的编码,它就不在是一个url了
上图limit设置一个大于它图片的大小,在页面中转换成了base64(文件一下就变大了很多,影响了文件的大小),可以通过这种方式来区分哪些图片应该打包成图片,哪些图片应该打包成base64
压缩图片 需要安装:npm install image-webpack-loader --save-dev
loaders可以包含多个loader;
Limit改变的,小于了,图片的大小,图片压缩打包之后图片大小变小(比原来的文件都小)
谢谢读者朋友耐心读完这篇文章。