webpack css loader加载器
- 什么是加载器 npm安装 正则表达式 loader打包
- loader解析 node npm
- 安装loader npm install XXX-loader –save–dev
webpack.config.js
|
|
- entry:配置入口文件的地址,可以是单一入口,也可以是多入口。
- output:配置出口文件的地址,在webpack2.X版本后,支持多出口配置。
- module:配置模块,主要是解析CSS和图片转换压缩等功能。
- plugins:配置插件,根据你的需要配置不同功能的插件。
- devServer:配置开发服务功能,
- http://jspang.com/2017/09/16/webpack3-2/
-devserver{}
- http://jspang.com/2017/09/16/webpack3-2/
设置webpack-dev-server
要执行webpack-dev-server是要先用npm install webpack-dev-server –save-dev 来进行下载的。下载好后,需要配置一下devServer。最简单的devServer配置项只有四个。先看一下代码,然后我再作解释。
/webpack.config.js
|
|
- contentBase:配置服务器基本运行路径,用于找到程序打包地址。
- host:服务运行地址,建议使用本机IP,这里为了讲解方便,所以用localhost。
- compress:服务器端压缩选型,一般设置为开启,如果你对服务器压缩感兴趣,可以自行学习。
- port:服务运行端口,建议不使用80,很容易被占用,这里使用了1717.
配置好后,你可以试着在终端中输入webpack-dev-server,如果可以执行成功,但是往往提示下面的错误(或者是无法找到内部或外部命令)。
出现下面的错误不用慌张,我们只要在package.json里配置一下scripts选项就可以执行了。
/package.json
|
|
在浏览器中自动打开
配置好保存后,在终端里输入 npm run server 打开服务器。然后在浏览器地址栏输入http://localhost:1717就可以看到结果了。
loader
loader的三种写法:
== css打包==
- 第一种写法:直接用use。12345678module:{rules:[{test:/\.css$/,use:['style-loader','css-loader']}]},
第二种写法:把use换成loader。
12345678module:{rules:[{test:/\.css$/,loader:['style-loader','css-loader']}]},第三种写法:用use+loader的写法:
1234567891011121314module:{rules:[{test:/\.css$/,use: [{loader: "style-loader"}, {loader: "css-loader"}]}]},
压缩JS代码:
现在你写的JS代码,在上线之前,都是需要进行压缩的,在没有webpack和gulp这些工具前,你可能需要找一个压缩软件或者在线进行压缩,在Webpack中可以很轻松的实现JS代码的压缩,它是通过插件的方式实现的,这里我们就先来引入一个uglifyjs-webpack-plugin(JS压缩插件,简称uglify)。
==注意==:虽然uglifyjs是插件,但是webpack版本里默认已经集成,不需要再次安装
我们需要在webpack.config.js中引入uglifyjs-webpack-glugin插件
12const uglify = require('uglifyjs-webpack-plugin');引入后在plugins配置里new一个 uglify对象就可以了,代码如下。
123plugins:[new uglify()],
打包HTML文件
我们先把dist中的html文件剪切到src目录中,并去掉我们的JS引入代码(webpack会自动为我们引入JS),因为这才是我们真实工作的目录文件结构。
然后我们配置webpack.config.js文件,先引入我们的html-webpack-plugin插件。
引入后使用npm进行安装包。
最后在webpack.config.js里的plugins里进行插件配置,配置代码如下。
- minify:是对html文件进行压缩,removeAttrubuteQuotes是却掉属性的双引号。
- hash:为了开发中js有缓存效果,所以加入hash,这样可以有效避免缓存JS。
- template:是要打包的html模版路径和文件名称。
上边的都配置完成后,我们就可以在终端中使用webpack,进行打包。你会看到index.html文件已经被打包到我们的dist目录下了,并且自动为我们引入了路口的JS文件。
图片迈坑:CSS中的图片处理
编写css文件,把你用的图片作为背景显示。
这时候打包就回报错
file-loader、url-loader
上面的错误是由于缺少loader的解析,对loader其实我们并不陌生,因为前边已经学习了CSS打包的loader。我们先安装两个解析图片用的loader。
安装file-loader和url-loader
==file-loader==:解决引用路径的问题,拿background样式用url引入背景图来说,我们都知道,webpack最终会将各个模块打包成一个文件,因此我们样式中的url路径是相对入口html页面的,而不是相对于原始css文件所在的路径的。这就会导致图片引入失败。这个问题是用file-loader解决的,file-loader可以解析项目中的url引入(不仅限于css),根据我们的配置,将图片拷贝到相应的路径,再根据我们的配置,修改打包后文件引用路径,使之指向正确的文件。
==url-loader==:如果图片较多,会发很多http请求,会降低页面性能。这个问题可以通过url-loader解决。url-loader会将引入的图片编码,生成dataURl。相当于把图片数据翻译成一串字符。再把这串字符打包到文件中,最终只需要引入这个文件就能访问图片了。当然,如果图片较大,编码会消耗性能。因此url-loader提供了一个limit参数,小于limit字节的文件会被转为DataURl,大于limit的还会使用file-loader进行copy。
==我们安装好后,就可以使用这个loader了,记得在loader使用时不需要用require引入,在plugins才需要使用require引入。==
webpack.config.js文件
//模块:例如解读CSS,图片如何转换,压缩
- test:/.(png|jpg|gif)/是匹配图片文件后缀名称。
- use:是指定使用的loader和loader的配置参数。
- limit:是把小于500000B的文件打成Base64的格式,写入JS。
图片迈坑:CSS分离与图片路径处理
==CSS分离==:extract-text-webpack-plugin
有些简单的交互页面中,你的JavasScript页面代码会非常少,而大部分代码都在CSS中,这时候项目组长会要求把CSS单独提取出来,方便以后更改。遇到这个需求你不要惊慌,已经有大神为我们准备好了对象的插件(plugin)。
这个插件就可以完美的解决我们提取CSS的需求,但是webpack官方其实并不建议这样作,他们认为CSS就应该打包到JavasScript当中以减少http的请求数。但现实中的需求往往不是我们前端能控制的,有些需求是我们不能控制的,分离CSS就是这样一个既合理由不合理的需求。
安装:
1npm install --save-dev extract-text-webpack-plugin引入:安装完成后,需要先用require引入。
1const extractTextPlugin = require("extract-text-webpack-plugin");设置Plugins:引入成功后需要在plugins属性中进行配置。这里只要new一下这个对象就可以了。
1new extractTextPlugin("/css/index.css")这里的/css/index.css是分离后的路径位置。这部配置完成后,包装代码:还要修改原来我们的style-loader和css-loader。
12345678910111213141516171819module:{rules: [{test: /\.css$/,use: extractTextPlugin.extract({fallback: "style-loader",use: "css-loader"})},{test:/\.(png|jpg|gif)/ ,use:[{loader:'url-loader',options:{limit:500000}}]}]},
图片路径问题:
利用extract-text-webpack-plugin插件很轻松的就把CSS文件分离了出来,但是CSS路径并不正确,很多小伙伴就在这里搞个几天还是没有头绪,网上也给出了很多的解决方案,我觉的最好的解决方案是使用publicPath解决,我也一直在用。
==publicPath==:是在webpack.config.js文件的output选项中,主要作用就是处理静态文件路径的。
在处理前,我们在webpack.config.js 上方声明一个对象,叫website。
注意,这里的IP和端口,是你本机的ip或者是你devServer配置的IP和端口。
然后在output选项中引用这个对象的publicPath属性。
配置完成后,你再使用webpack命令进行打包,你会发现原来的相对路径改为了绝对路径,这样来讲速度更快。
html-withimg-loader
html-withimg-loader就是我们今天的重点了,这个插件并不是很火,也是我个人喜欢的一个小loader。解决的问题就是在hmtl文件中引入 img标签的问题。
安装:
|
|
配置loader
webpack.config.js
然后在终端中可以进行打包了。你会发现images被很好的打包了。并且路径也完全正确。
CSS进阶:Less文件的打包和分离
打包Less文件
安装:
还需要安装Less-loader用来打包使用。
写loader配置:
安装好后,需要在webpack.config.js里编写loader配置,当然要想正确解析成CSS,还是需要style-loader和css-loader的帮助,
webpack.config.js
|
|
编写一个less文件
black.less
|
|
引入到我们entery.js文件中
|
|
这样我们就可以把less文件进行打包了。我们可以使用webpack命令打包试一试
把Lees文件分离。
我们之前讲了extract-text-webpack-plugin这个插件,想把Less文件分离出来的方法跟这个几乎一样,这里我们就只讲less的loader配置方法
|
|
配置好后,你会发现less被分离到了index.css文件里。
CSS进阶:SASS文件的打包和分离
安装SASS打包的loader
这里需要 在项目目录下用npm安装两个包。node-sass和sass-loader
node-sass:因为sass-loader依赖于node-sass,所以需要先安装node-sass
|
|
sass-loader:
==注意:在用npm安装时,这个loader很容易安装失败,最好使用cnpm来进行安装。如果你安装一直报错,最好是把node_modules文件夹删除后,再重新安装。==
编写loader配置
需要注意的是loader的加载要有先后顺序。
写好loader配置后,就可以愉快的编写sass文件拉,但是不要忘记把sass文件引入到entery.js中。
|
|
都完成后,你就可以启动我们npm run server 来查看效果了
把SASS文件分离。
|
|
CSS进阶:自动处理CSS3属性前缀
PostCSS
==这里给出postcss-loader的github地址:https://github.com/postcss/postcss-loader==
PostCSS是一个CSS的处理平台,它可以帮助你的CSS实现更多的功能,但是今天我们就通过其中的一个加前缀的功能,初步了解一下PostCSS。
安装
需要安装两个包postcss-loader 和autoprefixer(自动添加前缀的插件)
|
|
postcss.config.js
postCSS推荐在项目根目录(和webpack.config.js同级),建立一个postcss.config.js文件。
postcss.config.js
|
|
这就是对postCSS一个简单的配置,引入了autoprefixer插件。让postCSS拥有添加前缀的能力,它会根据 can i use 来增加相应的css3属性前缀。
编写loader
对postcss.config.js配置完成后,我们还需要编写我们的loader配置。
提取CSS
配置提取CSS的loader配置. webpack.config.js
|
|
CSS进阶:消除未使用的CSS
PurifyCSS
使用PurifyCSS可以大大减少CSS冗余,比如我们经常使用的BootStrap(140KB)就可以减少到只有35KB大小。这在实际开发当中是非常有用的
安装PurifyCSS-webpack
从名字你就可以看出这是一个插件,而不是loader。所以这个需要安装还需要引入。 PurifyCSS-webpack要以来于purify-css这个包,所以这两个都需要安装。
|
|
这里的-D代表的是–save-dev ,只是一个简写。
引入glob
因为我们需要同步检查html模板,所以我们需要引入node的glob对象使用。在webpack.config.js文件头部引入glob。
|
|
引入purifycss-webpack
同样在webpack.config.js文件头部引入purifycss-webpack
|
|
配置plugins
引入完成后我们需要在webpack.config.js里配置plugins。代码如下,重点看标黄部分。
|
|
这里配置了一个paths,主要是需找html模板,purifycss根据这个配置会遍历你的文件,查找哪些css被使用了。
==注意==:使用这个插件必须配合extract-text-webpack-plugin这个插件
给webpack增加babel支持
Babel其实是一个编译JavaScript的平台,它的强大之处表现在可以通过便宜帮你达到以下目的:
- 使用下一代的javaScript代码(ES6,ES7….),即使这些标准目前并未被当前的浏览器完全支持。
- 使用基于JavaScript进行了扩展的语言,比如React的JSX。
Babel的安装与配置
Babel其实是几个模块化的包,其核心功能位于称为babel-core的npm包中,webpack可以把其不同的包整合在一起使用,对于每一个你需要的功能或拓展,你都需要安装单独的包(用得最多的是解析ES6的babel-preset-es2015包和解析JSX的babel-preset-react包)。
我们先一次性安装这些依赖包
|
|
在webpack中配置Babel的方法如下:
|
|
现在你已经可以用webapck转换ES6的语法兼容各个浏览器了,我们可以修改一下entry.js的代码如下
|
|
上面的代码使用了ES6的let声明方法。如果你不使用Babel来进行转换,你会发现打包出来的js代码没有作兼容处理,使用了Babel转换的代码是进行处理过的
.babelrc配置
虽然Babel可以直接在webpack.config.js中进行配置,但是考虑到babel具有非常多的配置选项,如果卸载webapck.config.js中会非常的雍长不可阅读,所以我们经常把配置卸载.babelrc文件里。
在项目根目录新建.babelrc文件,并把配置写到文件里。
.babelrc
|
|
.webpack.config.js里的loader配置
|
|
ENV:
现在网络上已经不流行babel-preset-es2015,现在官方推荐使用的是babel-preset-env,那我们为了紧跟潮流,我们在讲一下env的配置方法。
首先需要下载:
|
|
然后修改.babelrc里的配置文件。其实只要把之前的es2015换成env就可以了.
|
|
总结:对于在React中Babel的使用,如何解析JSX,我会在后边的课程作详细了解,大家不要着急。在实际工作中还是要安装Babel的,这样能更好的兼容每种浏览器,而把Babel的配置文件分解出来是最好的选择。
打包后如何调试
在使用webpack时只要通过简单的devtool配置,webapck就会自动给我们生产source maps 文件,map文件是一种对应编译文件和源文件的方法,让我们调试起来更简单。
四种选项
在配置devtool时,webpack给我们提供了四种选项。
- source-map:在一个单独文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包速度;
- cheap-module-source-map:在一个单独的文件中产生一个不带列映射的map,不带列映射提高了打包速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便。
- eval-source-map:使用eval打包源文件模块,在同一个文件中生产干净的完整版的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。在开发阶段这是一个非常好的选项,在生产阶段则一定要不开启这个选项。
- cheap-module-eval-source-map:这是在打包文件时最快的生产source map的方法,生产的 Source map 会和打包后的JavaScript文件同行显示,没有影射列,和eval-source-map选项具有相似的缺点
四种打包模式,有上到下打包速度越来越快,不过同时也具有越来越多的负面作用,较快的打包速度的后果就是对执行和调试有一定的影响。
个人意见是,如果大型项目可以使用source-map,如果是中小型项目使用eval-source-map就完全可以应对,需要强调说明的是,source map只适用于开发阶段,上线前记得修改这些调试设置。
简单的配置:
|
|
总结:调试在开发中也是必不可少的,但是一定要记得在上线前一定要修改webpack配置,在打出上线包。
开发和生产并行设置
我们在以前的配置中设置了一个变量website,用于静态资源正确找到路径。那如果生产环境和开发环境不一样,而且我们需要来回切换,这时候我们需要更好的设置方法。
|
|
修改package.json命令
其实就是添加一个dev设置,并通过环境变量来进行区分,下面是package.json里的值。
|
|
修改webpack.config.js文件
可以利用node的语法来读取type的值,然后根据type的值用if–else判断
|
|
如果你说我想看一下传过来的值到底是什么?可以用下面的输出语句.
|
|
Mac下的package.json设置
MAC电脑下需要把set换成export,并且要多加一个&符,具体代码如下
|
|
实战技巧:webpack模块化配置
看下面ES6中的模块化代码。
|
|
上面的代码是一个最简单的es6模块化写法,我们声明了一个jspang方法,并且把这个方法用module.exports进行暴露出去。然后我们在入口文件中用import进行引入,并进行使用。
|
|
我们了解如何作Javascript的模块化后,其实webpack的模块化和上边的过程很类似
webpack模块
为了让大家容易看懂,我把webpack.config.js中的entry入口文件进行模块化设置,单独拿出来制作成一个模块。
首先在根目录,新建一个webpack_config文件夹,然后新建entry_webpack.js文件,代码如下:
entry_webpack.js
|
|
配置的模块化代码编写好以后,需要在webpack.config.js中引入,注意这里的引入只能使用require的方法。
|
|
然后在入口文件部分,修改成如下代码:
|
|
这时候你可以再次使用npm run dev 进行测试,你会发现模块化成功了
优雅打包第三方类库
引入JQuery
其实引用第三方库的方法有很多种,但是有些并不是很优雅,还有些方法会出现打包问题,技术胖在这里介绍一下自己工作中引入第三方模块的方法,我们就拿JQuery为例。小伙伴们要举一反三,学会后试着自己引入Vue试试。
安装JQuery
|
|
安装时需要注意的时Jquery最终要在生产环境中使用,所以我们这里要使用–save进行安装。
修改entry.js文件
安装好后,还需要引入到我们的entry.js中,这里直接使用import进行引入就可以。
|
|
可以看到上面是标准的jquery代码,你可以使用npm run server 进行测试,现在代码顺利运行了,这说明我们引用的JQuery库成功了。需要说的是你不仅可以在入口中进行引入,你还可以在任何你需要的js中引入,webpack并不会重复打包,它只给我们打包一次。
用plugin引入
如果你觉的上面的方法和webpack没什么关系,只是普通的引入,webpack只是负责了一下打包,这样并没有全局感。那再学习一种在webapck.config.js中配置的方法,这种不需要你在入口文件中引入,而是webpack给你作了全局引入。这个插件就是ProvidePlugin。
ProvidePlugin是一个webpack自带的插件,Provide的意思就是装备、提供。因为ProvidePlugin是webpack自带的插件,所以要先再webpack.config.js中引入webpack。
|
|
在webpack.config.js里引入必须使用require,否则会报错的,这点小伙伴们一定要注意。
引入成功后配置我们的plugins模块,代码如下。
|
|
配置好后,就可以在你的入口文件中使用了,而不用再次引入了。这是一种全局的引入,在实际工作中也可以很好的规范项目所使用的第三方库
实战技巧:watch的正确使用方法
在初级开发阶段,使用webpack-dev-server就可以充当服务器和完成打包任务,但时随着你项目的进一步完成,可能需要前后台联调或者两个前端合并代码时,就需要一个公共的服务器了。这时候我们每次保存后手动打包显然效率太低,我们希望的场景是代码发生变化后,只要保存,webpack自动为我们进行打包。这个工具就是watch,这节课我们把wacht完全学会,你会发现在开发中更加的得心应手
watch的配置
很多小伙伴认为–warch直接使用就可以,并没有什么需要讲的。其实这只是初级的用法,但是在学习一种技术时,我们必须要做到了解全部,也就是常说的知其然知其所以然。我们看下面的配置代码,我在代码中已经做出了解释。
watchOptions:{
//检测修改的时间,以毫秒为单位
poll:1000,
//防止重复保存而发生重复编译错误。这里设置的500是半秒内重复保存,不进行打包操作
aggregateTimeout:500,
//不监听的目录
ignored:/node_modules/,
}
上边的每一行配置我都作了说明,有时候你在没配置的情况下,直接用webpack –watch是不起作用的,这时候你需要进行配置这些选项。
配置好后,我们就可以痛快的使用watch了,在大型项目中,这大大加快了我们的开发效率,不用反复的手动打包了。
BannerPlugin插件
由于这节课的内容太少了,我们再讲一个工作中的小技巧,再工作中每个人写的代码都要写上备注,为的就是在发生问题时可以找到当时写代码的人。有时候也用于版权声明。
这个插件就是BannerPlugin,我们使用后会在JS中加上我们的版权或开发者声明。
|
|
需要注意的是在使用这个插件之前必须引入webpack。
|
|
这时在dist目录下的entery.js已经加上了版权声明。
webpack优化黑技能
作为一个程序员,无论是写什么程序都i要有一颗不断优化的心。webpack在优化这条路上,也为我们作了很多配置,这节课我们就看看工作中常用的webpack优化黑技能。
ProvidePlugin和import
在第19节中学习了如何引入第三方类库,并引入了jquery,在引用JQuery时我们用了两种方法,第一种时import,第二种时使用ProvidePlugin插件。那两种引入方法有什么区别那?
- import引入方法:引用后不管你在代码中使用不适用该类库,都会把该类库打包起来,这样有时就会让代码产生冗余。
- ProvidePlugin引入方法:引用后只有在类库使用时,才按需进行打包,所以建议在工作使用插件的方式进行引入。
抽离JQuery
上边的方法只是优化的第一步,工作中你会发现,不适用的类库几乎我们也不会引入,所以上边只是一个必要操作的第一步。那往往把第三方类库抽离出来,才是最好的解决方法。
第一步:修改入口文件
抽离的第一步是修改入口文件,把我们的JQuery也加入到入口文件中,看下面的代码。
webpack.config.js
第二步:引入插件
我们需要引入optimize优化插件,插件里边是需要配置的,具体配置项看下面的代码。
minChunks一般都是固定配置,但是不写是不行的,你会打包失败。
filename是可以省略的,这是直接打包到了打包根目录下,我们这里直接打包到了dist文件夹下边。
配置完成后,我们可以先删掉以前打包的dist目录,然后用webpack再次打包,你会发现jquery被抽离了出来,并且我们的entry.js文件变的很小。
多个第三方类库抽离
会了如何抽离Jquery,但是在实际开发中,我们会引用不止一个第三方类库,这时也需要抽离。我们拿引入Vue为例,看看如何抽离出来。
第一步:我们先用npm 进行安装。
|
|
注意这里是–save,而不是–save-dev。因为这个类库在生产环境中也是要使用的。
第二步:在入口配置中引入vue和jquery
|
|
只是多比上边多加了一个vue选项。
第三步:修改CommonsChunkPlugin配置
需要修改两个位置:
- 第一个是在name属性里把原来的字符串改为数组,因为我们要引入多个模块,所以是数组;
- 第二个是在filename属性中把我们输出的文件名改为匹配付[name],这项操作就是打包出来的名字跟随我们打包前的模块。
下面是我们修改的代码,你可以跟jquery抽离时对比一下。
- 也可以配置后缀名[ext]
|
|
配置好后,我们就可以在控制台输入webpack进行打包了。你会看到我们预想的结果,jquery和vue都被我们抽离出来了
实战技巧:静态资源集中输出
工作中会有一些已经存在但在项目中没有引用的图片资源或者其他静态资源(比如设计图、开发文档),这些静态资源有可能是文档,也有可能是一些额外的图片。项目组长会要求你打包时保留这些静态资源,直接打包到制定文件夹。其实打包这些资源只需要用到copy-webpack-plugin。
使用copy-webpack-plugin
copy-webpack-plugin就是专门为我们作静态资源转移的插件,不过它不同上两节使用的插件,它是需要安装的。
插件安装
插件的安装只要使用npm就可以了
。
|
|
如果在安装过程中出错,你可以使用npm来进行安装。
引入插件
安装好后,需要在webpack.config.js文件的头部引入这个插件才可以使用。
|
|
配置插件
引入之后我们就可以在plugins里边进行配置插件了,我们先看下面的插件配置代码,然后再进行详细讲解。
|
|
- from:要打包的静态资源目录地址,这里的__dirname是指项目目录下,是node的一种语法,可以直接定位到本机的项目目录中。
- to:要打包到的文件夹路径,跟随output配置中的目录。所以不需要再自己加__dirname。
实战技巧:Json配置文件使用
在实际工作中,我们的项目都会配置一个Json的文件或者说API文件,作为项目的配置文件。有时候你也会从后台读取到一个json的文件,这节课就学习如何在webpack环境中使用Json。如果你会webpack1或者webpack2版本中,你是需要加载一个json-loader的loader进来的,但是在webpack3.x版本中,你不再需要另外引入了。
读出Json内容
第一步:现在我们的index.html模板中加入一个层,并给层一个Id,为了是在javascript代码中可以方便引用。
|
|
第二步:到src文件夹下,找到入口文件,我这里是entry.js文件。修改里边的代码,如下:
|
|
这两行代码非常简单,第一行是引入我们的json文件,第二行驶写入到到DOM中。
第三部:启用我们的npm run server 命令就可以在浏览器中看到结果了。
说说热更新
其实在webpack3中启用热加载相当的容易,只要加入HotModuleReplacementPlugin这个插件就可以了。
|
|
现在只要你启动 npm run server 后,修改index.html中的内容,浏览器可以自动给我们更新出最新的页面。
但这里说的热加更新和我们平时写程序的热加载不是一回事,比如说我们Vue或者React中的热更新,并不是刷新整个页面,而是一个局部更新,而这里的更新是重新刷新了页面。
这点小伙伴们要搞清楚。
。