Loaders是Webpack最重要的功能之一,他也是Webpack如此盛行的原因。通过使用不同的Loader,Webpack可以的脚本和工具,从而对不同的文件格式进行特定处理。
Webpack的API:
Webpack使用loader
http://webpack.github.io/docs/using-loaders.html
webpack的API中使用module-loader(包括include,exclude等)
http://webpack.github.io/docs/configuration.html#module-loaders
简单的举几个Loaders使用例子:
注意:所有的Loaders都需要在npm中单独进行安装,并在webpack.config.js里进行配置。下面我们对Loaders的配置型简单梳理一下。
第一种写法:直接用use。
module:{
rules:[
{
test:/\.css$/,
use:['style-loader','css-loader']
}
]
},
第二种写法:把use换成loader
module:{
rules:[
{
test:/\.css$/,
loader:['style-loader','css-loader']
}
]
},
第三种写法:用use+loader的写法:
module:{
rules:[
{
test:/\.css$/,
use: [
{
loader: "style-loader"
}, {
loader: "css-loader"
}
]
}
]
}
在我的上一篇的博客中已经介绍了生成html文件,这里就不再多说了。
node的path的用法
http://nodejs.cn/api/path.html#path_path_resolve_paths
这里我们需要两个解析用的loader,分别是style-loader和css-loader。
style-loader:
它是用来处理css文件中的url()等,npm中的网址:https://www.npmjs.com/package/style-loader
npm install style-loader --save-dev
css-loader:
它是用来将css插入到页面的style标签。npm中的网址:https://www.npmjs.com/package/css-loader
npm install --save-dev css-loader
body {
background: red;
}
entry.js
import css from './style.css'
console.log('pp');
webpack.config.js
const path = require('path');
const htmlPlugin= require('html-webpack-plugin');
module.exports = {
entry: {
entry: __dirname + '/src/entry.js'
},
output: {
path: __dirname + '/dist',
filename: '[name].js'
},
//通过配置将加载器绑定到RegExp(正则表达式)
module: {
rules: [
//对所有的css使用style-loader和css-loader
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
}
]
},
//使用html模板插件
plugins: [
new htmlPlugin({
minify: {
removeAttributeQuotes:true
},
hash:true,
template: __dirname + '/src/index.html'
})
]
}
执行webpack打包后:
可以看到生成了dist文件夹,dist文件夹中并没有css,这是因为css被打包到了entry.js中,所有的引用的资源都是以js的形式被引用。
loader的使用是有顺序的,是从后向前,从右向左的。 比如我们使用先使用css-loader是因为要将css插入到页面的style标签中,style-loader是识别插入后的css中的url等。。。
在src目录下新建一个images文件夹,把图片放入images文件夹。
在index.html文件中增加一个放置div的标签(需要注意的是这里修改的是src下的index.html文件,不是dist下的,这点新手很容易弄混,要格外注意),代码如下
<div id="hcd"></div>
编写css文件,设置hcd盒子的背景
#hcd {
width: 400px;
height: 400px;
background-image: url(./img/IMG_2009.JPG);
}
npm install --save-dev file-loader url-loader img-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(64位的编码),大于limit的还会使用file-loader进行copy***。在内部引用了file-loader,所以想用url-loader必须引用file-loader
img-loader
https://www.npmjs.com/package/img-loader
需要配合url-loader或者file-loader一起使用,img-loader是可以根据不同的图片类型进行不同的设置
压缩打包的图片,原来的图片是132k的,压缩后只有57.4k
用file-loader,http请求图片可以起到一定的缓存作用,当有图片重复时,不会再次加载了
用url-loader,代码每次都会出现,增加代码的体积,影响HTML和js的大小
webpack.config.js文件
const path = require('path');
const htmlPlugin= require('html-webpack-plugin');
module.exports = {
entry: {
entry: __dirname + '/src/entry.js'
},
output: {
path: __dirname + '/dist',
filename: '[name].js'
},
//通过配置将加载器绑定到RegExp(正则表达式)
module: {
rules: [
//对所有的css使用style-loader和css-loader
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
},
//对图片使用url-loader
{
test: /\.(img|jpg|png)/i,
use:[{
loader: 'url-loader',
//通过options给url-loader设置参数
options: {
//图片小于5000b就变为base64位编码
limits: 5000,
//将超出limit的图面放到dist目录下的images
outputPath:'images/'
}
}]
}
]
},
plugins: [
new htmlPlugin({
minify: {
removeAttributeQuotes:true
},
hash:true,
template: __dirname + '/src/index.html'
})
]
}
直接使用webpack打包就可以了
在css中引入(layer.less)
在入口的index.html文件中引入
在HTML模板文件中引入
Webpack.config.js
1.file-loader
//file-loader
{
test: /\.(png|gif|jpe?g|svg)$/i,
loader: 'file-loader',
// 设置编译后图片的地址和名称
// 放在outpath.path:__dirname+'/dist'下的assets文件夹下
// [文件名]-[5位的hash].[文件后缀]
options: {
name: 'assets/[name]-[hash:5].[ext]'
}
}
2.url-loader
// url-loader
{
test: /\.(png|gif|jpe?g|svg)$/i,
loader: 'url-loader',
//设置参数
//limit表示img大于140k的用http请求,小于140k的用base64
// 设置编译后图片的地址和名称
// 放在outpath.path:__dirname+'/dist'下的assets文件夹下
// [文件名]-[5位的hash].[文件后缀]
options: {
limit:1400000,
name: 'assets/[name]-[hash:5].[ext]'
}
}
3.img-loader
1 //img-loader(图片压缩需要和url-loader或者file-loader一起使用)
2 {
3 test: /\.(png|gif|jpe?g|svg)$/i,
4 loaders:[
5 'url-loader?limit=1400&name=assets/[name]-[hash:5].[ext]',
6 'img-loader'
7 ]
8 }
extract-text-webpack-plugin 我们将利用这个plugin解决,但是webpack官方其实并不建议这样作,他们认为CSS就应该打包到JavasScript当中以减少http的请求数。但现实中的需求往往不是我们前端能控制的,有些需求是我们不能控制的,分离CSS就是这样一个既合理由不合理的需求。
API:https://www.npmjs.com/package/extract-text-webpack-plugin
安装:
npm install --save-dev extract-text-webpack-plugin
配置plugin
const path = require('path');
const htmlPlugin= require('html-webpack-plugin');
// 引用插件
const extractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: {
entry: __dirname + '/src/entry.js'
},
output: {
path: __dirname + '/dist',
filename: '[name].js'
},
module: {
rules: [
{
test: /\.css$/,
//对所有的css使用插件的extract方法
use: extractTextPlugin.extract({
fallback: 'style-loader',
use:'css-loader'
})
},
{
test: /\.(img|jpg|png)/i,
use:[{
loader: 'url-loader',
options: {
limits: 5000
}
}]
}
]
},
plugins: [
new htmlPlugin({
minify: {
removeAttributeQuotes:true
},
hash:true,
template: __dirname + '/src/index.html'
}),
//初始化extract-text-webpack-plugin,设置打包后分离的css在打包文件dist的路径位置
new extractTextPlugin('/style/index.css')
]
}
利用extract-text-webpack-plugin
插件很轻松的就把CSS文件分离了出来,但是CSS路径并不正确
我们将使用publicPath解决
publicPath:是在webpack.config.js
文件的output选项中,主要作用就是***处理静态文件路径***的。
我们在output中设置
webpack.config.js
const path = require('path');
const htmlPlugin= require('html-webpack-plugin');
const extractTextPlugin = require('extract-text-webpack-plugin');
//设置对象
const website = {
//是你本机的ip或者是你devServer热更新配置的IP和端口。或者上线后的图片网址,
publicPath: 'http://192.168.0.118:1717/'
};
module.exports = {
entry: {
entry: __dirname + '/src/entry.js'
},
output: {
path: __dirname + '/dist',
filename: '[name].js',
//给所有打包的资源的路径都设置为我们想要的path
publicPath:website.publicPath
},
。。。。。
}
在webpack中是不喜欢你使用标签 img 来引入图片的,但是我们作前端的人特别热衷于这种写法,国人也为此开发了一个:html-withimg-loader。他可以很好的处理我们在html 中引入图片的问题。
安装
npm install html-withimg-loader --save
配置loader
{
//对所用的html文件使用loader
test: /\.(htm|html)$/i,
use:[ 'html-withimg-loader']
}
#4.使用Less
首先安装Less的服务
npm install --save-dev less
安装less-loader
npm install --save-dev less-loader
loader的配置
//判断所有的less
{
test: /\.less$/,
//顺序是先使用less-loader转为css,后用css-loader插入style标签,最后是用style-loader解析
use: [{
loader: 'style-loader'
},{
loader: 'css-loader'
},{
loader: 'less-loader'
}]
}
我们编写一个less文件:
@base :#000;
#gogo{
width:300px;
height:300px;
background-color:@base;
}
这里#gogo
是层的ID名称。@base
是我们设置的变量名称。
引入到我们entery.js文件中
import less from './css/black.less';
执行webpack命令就可以了
利用上面讲的extract-text-webpack-plugin
loader配置方法
{
test: /\.less$/,
use: extractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader','less-loader']
})
}
安装SASS打包的loader
这里需要 在项目目录下用npm安装两个包。node-sass和sass-loader
node-sass:因为sass-loader依赖于node-sass,所以需要先安装node-sass
npm install --save-dev node-sass
sass-loader:
npm install --save-dev sass-loader
编写loader配置
{
test: /\.scss$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "sass-loader" // compiles Sass to CSS
}]
}
使用和less基本是一样的
loader的使用是有顺序的,是从后向前,从右向左的。 比如我们使用先使用css-loader是因为要将css插入到页面的style标签中,style-loader是识别插入后的css中的url等。。。
如果有了less-loader(sass-loader)就要先使用less-loader,因为要先将less或是sass转为css
PostCSS :
PostCSS是一个CSS的处理平台,它可以帮助你的CSS实现更多的功能,但是今天我们就通过其中的一个加前缀的功能,初步了解一下PostCSS。
需要安装两个包postcss-loader 和autoprefixer(自动添加前缀的插件)
npm install --save-dev postcss-loader autoprefixer
postCSS推荐在项目根目录(和webpack.config.js同级),建立一个postcss.config.js文件。
内容为:
//引用postcss的自动补充插件
module.exports = {
plugins:[
require('autoprefixer')
]
}
对postcss.config.js配置完成后,我们还需要在webpack.config.js中编写我们的loader配置
{
test: /\.css$/,
use: [
{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
//注意位置,首先使用的是postcss-loader来补全css(loader是从后先前读的)
loader: "postcss-loader"
}
]
}
{
test: /\.css$/,
use: extractTextPlugin.extract({
fallback: 'style-loader',
//注意位置,首先使用的是postcss-loader来补全css(loader是从右向左读的)
use:['css-loader','postcss-loader']
})
},
像Bootstrap这样的框架往往会带有很多CSS。在项目中通常我们只使用它的一小部分。就算我们自己写CSS,随着项目的进展,CSS也会越来越多,有时候需求更改,带来了DOM结构的更改,这时候我们可能无暇关注CSS样式,造成很多CSS的冗余。
使用PurifyCSS可以大大减少CSS冗余,比如我们经常使用的BootStrap(140KB)就可以减少到只有35KB大小。这在实际开发当中是非常有用的。
从名字你就可以看出这是一个插件,而不是loader。所以这个需要安装还需要引入。 PurifyCSS-webpack要以来于purify-css这个包,所以这两个都需要安装。
npm install --save-dev purifycss-webpack purify-css
webpack.config.js
头部的引用:
//因为我们要检查html的所有的DOM,已确定是否有多余的css所以webpack.config.js的首部引入glod
const glob = require('glob');
//引用purifycss-webpack 插件
const purifyPlugin = require('purifycss-webpack');
具体的插件配置:
plugins: [
new purifyPlugin({
// paths表示我们要查找的html(绝对路径下的)模板
paths: glob.sync(path.join(__dirname,'src/*html'))
})
]
再执行webapck命令 会发现多余的css在打包后的css文件中找不到了
现在你写的JS代码,在上线之前,都是需要进行压缩的,在没有webpack和gulp这些工具前,你可能需要找一个压缩软件或者在线进行压缩,在Webpack中可以很轻松的实现JS代码的压缩,它是通过插件的方式实现的,这里我们就先来引入一个uglifyjs-webpack-plugin(JS压缩插件,简称uglify)。
虽然uglifyjs是插件,但是webpack版本里默认已经集成,不需要再次安装。
我们需要在***webpack.config.js***中引入uglifyjs-webpack-glugin插件
const uglify = require('uglifyjs-webpack-plugin');
引入后在plugins配置里new一个 uglify对象就可以了,代码如下。
plugins:[
new uglify()
],
转译工具babel
Babel中在webpack中的使用
http://babeljs.cn/docs/setup/#webpack
node的path的用法
http://nodejs.cn/api/path.html#path_path_resolve_paths
安装:
Babel安装:
npm install --save –dev babel-loader babel-core
es2015安装
npm install bable-preset-es2015
Webpack.config.js
var htmlWebpackPlugin = require('html-webpack-plugin');
// 因为要用绝对路径,所以我们使用node.js自带的path
var path = require('path');
module.exports = {
entry:'./src/app.js',
output:{
path:__dirname+'/dist',
filename:'js/[name]-bundle.js'
},
// 通过配置将加载器绑定到RegExp(正则表达式)
//ES6的转译插件babel
module:{
loaders:[
{
//检测所有的js文件
test: /\.js$/,
//使用babel-loader
loader: "babel-loader",
//不用使用(使用绝对路径)的数组
//path.resolve可以得出绝对路径
exclude:[
path.resolve(__dirname,'node_modules/'),
path.resolve(__dirname,'dist/')
],
// 只是src下的js使用(使用绝对路径)
//因为es6是不断更新的,babel转译es6是有不同版本的,这里采用‘es2015’版,也可以在loader?presets='es2015'表示
query:{
presets:['es2015']
}
}
]
},
plugins:[
new htmlWebpackPlugin({
template:'index.html',
filename:'index.html',
title:'this is C',
inject:'body'
})
]
}
如果你觉得看着麻烦:
{
test:/\.(jsx|js)$/,
use:{
loader:'babel-loader',
options:{
presets:[
"es2015"
]
}
},
exclude:/node_modules/
}
虽然Babel可以直接在webpack.config.js中进行配置,但是考虑到babel具有非常多的配置选项,如果卸载webapck.config.js中会非常的雍长不可阅读,所以我们经常把配置写在.babelrc文件里。
在项目根目录新建.babelrc文件。
将配置写在其中
{
"presets": [
"es2015"
]
}
webpack.config.js里的loader配置
{
test:/\.(jsx|js)$/,
use:{
loader:'babel-loader',
},
exclude:/node_modules/
}
现在网络上已经不流行babel-preset-es2015,现在官方推荐使用的是babel-preset-env
下载:
npm install --save-dev babel-preset-env
然后修改.babelrc里的配置文件。其实只要把之前的es2015换成env就可以了。
{
"presets":["env"]
}
API:http://webpack.github.io/docs/list-of-loaders.html#templating
html模板插件
npm install html-loader –save-dev
jade模板
npm install jade-loader –save-dev
ejs模板
npm install ejs-loader –save-dev
Layer.js
//引入html模板 其实是字符串
import tpl from './layer.html';
//引入ejs模板 其实是函数(用时可能会需要传入参数)
import ejs from './layerEjs.ejs';
function layer(){
return{
name:'layer',
tpl:tpl,
ejs:ejs
}
}
Export default layer
app.js
import './css/common.css';
import layer from './components/layer/layer.js';
import less from './components/layer/layer.less';
const app = function(){
var dom = document.getElementById('app');
var newLayer = layer();
//模板其实就是newLayer.tpl属性,将模板当做字符串
dom.innerHTML = newLayer.tpl;
var ejsdom = document.getElementById('ejsdiv');
//向ejs模板中传递参数
ejsdom.innerHTML = newLayer.ejs({
name:'hcd',
arr:['apple','xiaomi','honor']
})
}
new app();