几个维度了解webpack(一)"/>
几个维度了解webpack(一)
几个维度理解webpack(一)
文章目录
- 几个维度理解webpack(一)
- 基于的版本
- webpack基础
- webpack了解
- 环境准备
- 版本
- 功能进化
- webpack概念
- entry
- Output
- Loaders
- Plugins
- 名词
- webpack使用
- 打包JS
- 编译ES6/7
- babel插件
- babel polyfill
- babel runtime transform
- TypeScript
- 提取共用代码
- 用webpack的CommonsChunkPlugin提取公共代码的3种方式
- 代码分割和懒加载
- 代码分割
- 懒加载
- 处理CSS文件
- 引入css
- style-loader
- css-loader
- css modules
- 配置less/sass
- 提取css代码
- Tree Shaking
- JS Tree Shaking
- CSS tree shaking
- 文件处理
- 图片处理
- 字体文件
- 第三方JS库
- 处理HTML文件
- 生成HTML
- html中引入的图片
- 配合优化
系列文章链接:几个维度理解webpack(二);几个维度理解webpack(三)
基于的版本
- webpack@3.10.0
- 下载
npm i webpack@3.10.0 --save-dev
webpack基础
webpack了解
环境准备
- 命令行工具
- 安装必须:node、webpack@3.10.0
版本
功能进化
- 1版本:
- 编译、打包;
- HMR(模块化更新)
- 代码分割
- 文件处理
- 2版本
- tree shaking
- ES module
- 动态Import()
- 新的文档
- 3版本
- Scope Hoisting(作用域提升),运行速度提升
- Magic Comments(配合动态的import使用)
webpack概念
entry
- 代码的入口
- 打包的入口
- 单个或者多个entry
- 多页面应用程序
- 单页面:业务代码和逻辑代码
- entry有几种使用方法:
- 字符串
entry:__dirname+'/src/script/main.js'
//对应
output:{path:__dirname+'/dist/js',filename:'bundle.js'
}
- 数组
entry:[__dirname+'/src/script/main.js',__dirname+'/src/script/a.js'
]
//对应
output:{path:__dirname+'/dist/js',filename:'bundle.js'
}
- 对象
entry:{main:__dirname+'/src/script/main.js',a:__dirname+'/src/script/a.js'
}
//对应
output:{path:__dirname+'/dist/js',filename:'[name]-[hash].js'
}
//or
output:{path:__dirname+'/dist/js',filename:'[name]-[chunkhash].js'}
Output
- 特点
- 打包生成的文件(bunble)
- 一个或多个
- 自定义规则
- output是指打包生成的文件
- entry中输入多个chunk时,为确保文件名唯一避免相互覆盖使用占位符命名filename;
- 生成的名字有三种占位符
- [name]是chunk的name;
- [hash]是本次打包的hash值,hash值相同;
- [chunkhash]是每个chunk的hash值,不同文件同次打包不相同,保证文件的唯一性,只有改变文件中的内容时hash才变化,未做改变的文件hash值不变;
- [ext]是源文件的后缀名占位符
Loaders
- 特点
- 处理文件
- 转化为模块
- 常用的loader
- 编译相关:babel-loader、ts-loader
- 样式相关:style-loader、css-loader、less-loader、postcss-loader
- 文件相关:file-loader、url-loader
Plugins
- 特点
- 参与打包整个过程
- 打包优化和压缩
- 配置编译时的变量
- 极其灵活
- 常用的Plugins
- 优化相关:CommonsChunkPlugin、UglifyjsWebpackPlugin等
- 功能相关:ExtractTextWebpackPlugin、HtmlWebpackPlugin、HotModuleReplacementPlugin、CopyWebpackPlugin等
名词
- chunk代码块
- bundle打包后的代码
- module模块
webpack使用
- webpack命令
- webpack -h 查询命令
- webpack -v 查询版本
- webpack配置
- 指定webpack配置文件:
webpack --config webpack.config.js
;
- 指定webpack配置文件:
- 第三方脚手架
打包JS
- 创建基础配置文件
webpack.config.js
- 指定配置文件名称
webpack --config webpack.config.js
- 配置文件
module.exports = {entry: {app: './app.js'},output: {filename: '[name].[hash:5].js'}
}
编译ES6/7
- 安装
npm i --save-dev babel-loader babel-core
- babel-loader
- babel-presets
- 指定babel按照什么规范打包语法;
- 一个规范的总结;
- 设定preset的targets参数,指定编译后的需要匹配的目标:
use: {loader: 'babel-loader',options: {presets: [['env', {'targets': {'browsers': ['> 1%', 'last 2 versions']}}]]}
},
babel插件
- babel polyfill、 babel runtime transform等,处理兼容的模块内的一些方法
babel polyfill
- 全局垫片:一旦引入,全局可调用;
- 为开发应用准备;
- 安装
npm i babel-polyfill --save
- 引入:
import 'babel-polyfill'
babel runtime transform
- 局部垫片
- 为开发框架准备
- 不会污染全局
- 安装
npm i babel-plugin-transform-runtime --save-dev
,npm i babel-runtime --save
- 配置在:.babelrc文件中
TypeScript
- 安装:
npm i typescript ts-loader --save-dev
,npm i typescript awesome-typescript-loader --save-dev
- 配置:tsconfig.json或者webpack.config.js
- 配置常用选项
- compilerOptions
- include
- exclude
提取共用代码
- CommonsChunkPlugin的配置
name和names
:chunk的名称,如果这个chunk已经在entry中定义,该chunk会被直接提取;如果没有定义,则生成一个空的chunk来提取其他所有chunk的公共代码。filename
:可以指定提取出的公共代码的文件名称,可以使用output配置项中文件名的占位符。未定义时使用name作为文件名。chunks
:可以指定要提取公共模块的源chunks,指定的chunk必须是公共chunk的子模块,如果没有指定则使用所有entry中定义的入口chunk。minChunks
:在一个模块被提取到公共chunk之前,它必须被最少minChunks个chunk所包含。(通俗的说就是一个模块至少要被minChunks个模块所引用,才能被提取到公共模块。)- 该数字必须不小于2或者不大于chunks的个数。默认值等于chunks的个数。
- 如果指定了Infinity,则创建一个公共chunk,但是不包含任何模块,内部是一些webpack生成的runtime代码和chunk自身包含的模块(如果chunk存在的话)。
- 优点
- 减少代码冗余
- 提高加载速度
- 安装
npm i
- 配置
- options.name or options.names
- options.filename
- options.minChunks
- options.chunks
- options.children
- options.deepChildren
- options.async
{plugins:[new webpack.optimize.CommonsChunkPlugin(option)]
}
- 场景
- 单页应用
- 单页 + 第三方依赖
- 单页 + 第三方依赖 + webpack生成代码
用webpack的CommonsChunkPlugin提取公共代码的3种方式
- 方式一:传入字符串参数
// 默认会把所有入口节点的公共代码提取出来,生成一个common.js
new webpack.optimize.CommonsChunkPlugin('common.js')
- 方式二:有选择的提取公共代码
//提供公共代码,默认会把所有入口节点的公共代码提取出来,生成一个common.js
// 只提取main节点和index节点
new webpack.optimize.CommonsChunkPlugin('common.js',['main','index']),
- 方式三:有选择性的提取(对象方式传参)
new webpack.optimize.CommonsChunkPlugin({name:'common', // 注意不要.js后缀chunks:['main','user','index']
}),
代码分割和懒加载
- 通过写代码的规则来规定某些要代码分割;
代码分割
- webpack内置方法
- require.ensure参数(四个)
- []:dependencies:引入模块,不执行
- callback:执行引入模块
- errorCallback:可省略
- chunkName:接受的参数
- require.include参数
- require.ensure参数(四个)
- ES2015的loader
- system.import() -> import()
- 场景
- 分离业务代码 和 第三方依赖
- 分离业务代码 和 业务公共代码和第三方依赖
- 分离首次加载 和 访问后加载的代码
懒加载
处理CSS文件
引入css
style-loader
- style-loader:创建style标签,在页面中;
- style-loader/url:将css文件在html中变成link标签引入;
- style-loader/useable:设置css可用不可用;
//webpack.config.js
{test: /\.css$/,use: [{loader: 'style-loader/useable'}, {loader: 'css-loader'}]
},
//app.js
import base from './css/base.css'
import common from './css/common.css'
var flag = false;
setInterval(function() {if (flag) {base.unuse();} else {base.use()}flag = !flag
}, 500)
- style-loader的options
- insertAt:插入的位置;
- insertInto:插入到dom;
- singleton:是否只使用一个style标签;
- transform:转化,浏览器环境下,插入到页面前面;
{test: /\.css$/,use: [{loader: 'style-loader',options: {insertInto: '#app',singleton: true,transform: './css.transform.js'}}, {loader: 'css-loader'}]
},
css-loader
- css-loader:是如何import一个css模块;
- css-loader的options
- alias:解析的别名
- importLoader:@import
- minimize:是否压缩
- modules:启用css-modules
- localIdentName:打包后的class名称;
- getLocalIdent:保证打包后的class名称和原class名称一致;
- 使用
localIdentName:'[path][name]_[local]--[hash:base64:5]'
来设置打包后的css文件中class的名称- path:被打包文件的路径;
- name:被打包文件的名称;
- local:被打包文件的class名;
{loader: 'css-loader',options: {minimize: true,modules: true,localIdentName: '[path][name]_[local]_[hash:base64:5]'}
}
css modules
- 安装
npm i postcss postcss-loader autoprefixer cssnano postcss-cssnext --save-dev
- css-nano:优化压缩css文件,css-loader底层就是用这个;
- Autoprefixer:自动添加css的前缀以匹配任何文件;
- 配置
{loader: 'postcss-loader',options: {ident: 'postcss',plugins: [require('autoprefixer')(),require('postcss-cssnext')()]}
},
-
Broswerslist指定匹配哪些浏览器
- 所有插件都公用:package.json
"browserslist":[">=1%","last 2 versions" ]
- 添加文件:.browserslistrc
-
postcss-import将引入的css插入到当前的css文件中;
-
postcss-url配合postcss-import使用;
配置less/sass
- 安装
npm i less-loader sass-loader less node-sass --save-dev
提取css代码
- 方法一:extract-loader
- 方法二:使用ExtractTextWebpackPlugin(推荐)
- 安装
npm i extract-text-webpack-plugin --save-dev
- 配置
- 安装
var ExtractTextWebpackPlugin = require('extract-text-webpack-plugin')
//配置插件
plugins: [new ExtractTextWebpackPlugin({filename: '[name].min.css',allChunks: false}),new PurifyCSS({paths: glob.sync([path.join(__dirname, './*.html'),path.join(__dirname, "./src/*.js")])}),//Tree Shaking不使用的代码不打包new webpack.optimize.UglifyJsPlugin()
]
//配置loader
{test: /\.less$/,use: ExtractTextWebpackPlugin.extract({fallback: {loader: 'style-loader',options: {singleton: true,transform: './css.transform.js'}},use: [{loader: 'css-loader',options: {// 压缩minimize: true,modules: true,localIdentName: '[local]',}}, {loader: 'less-loader'}]})
}
- 生成app.min.css文件后是不会自动加载进入index.html中的,需要我们手动加载进去。
<link rel="stylesheet" href="./dist/app.min.css">
Tree Shaking
- 不使用的代码不打包进入;
- 包括:JS Tree Shaking和CSS Tree Shaking
- 使用场景
- 常规优化
- 引入第三方库的某一个功能
JS Tree Shaking
- 使用插件帮助:Webpack.optimize.uglifyJS
var webpack = require('webpack')
new Webpack.optimize.UglifyJsPlugin()
CSS tree shaking
- 使用purifycss-webpack
- 安装
npm i purifycss-webpack glob-all purify-css --save-dev
- 配置
- path:glob.sync([])
- 安装
- 使用glob-all处理多路径
var PurifyCSS = require("purifycss-webpack");
new PurifyCSS({paths: glob.sync([path.join(__dirname, './*.html'),path.join(__dirname, "./src/*.js")])
}),
文件处理
- 处理文件内容
- 图片文件
- 字体文件
- 第三方JS库
图片处理
- css中引入的图片的处理
- 自动合成雪碧图
- 压缩图片
- Base64编码
- 使用:file-loader,url-loader,img-loader,postcss-sprites
- 安装
npm i file-loader url-loader img-loader postcss-sprites --save-dev
- 图片打包的配置
//
{test: /\.(jpg|img|png|gif|svg|jpeg)$/,use: [{loader: 'file-loader',options: {publicPath: '',//outputPath: '',//将打包生成的文件关联原文件夹useRelativePath: true}//如果想根据图片大小来进行打包,可以这样设置loader: 'url-loader',options: {//当图片大小小于限制时会自动转成 base64 码引用limit: 200}}]
}//注意,输出的路径要将dist/注掉,不然打包出来的文件路径会多出来一层dist/output: {path: path.resolve(__dirname, 'dist'),//publicPath: 'dist/',filename: '[name].bundle.js',//chunkFilename: '[name].chunk.js'
},
- 图片合成雪碧图的配置
//在postcss-loader的配置中引入postcss-sprites,进行设置
{//处理css文件loader: 'postcss-loader',options: {ident: 'postcss',plugins: [//打包生成雪碧图的配置require('postcss-sprites')({//雪碧图打包后的地址spritePath: 'dist/assets/imgs/sprites',//适应高分辨率视口retina: true}),//require('autoprefixer')(),require('postcss-cssnext')()]}
}//修改雪碧图的名字
{ loader: 'url-loader',options: {name: '[name]-min.[ext]',limit: 200,//publicPath: '',//outputPath: '',//将打包生成的文件关联原文件夹useRelativePath: true}
},
字体文件
- 字体文件后缀名
- eot,woff2,ttf,svg
{test:/\.(eot|woff2?|ttf|svg)$/,use:[{loader:'url-loader',options:{name: '[name]-min.[ext]',limit: 200,//将打包生成的文件关联原文件夹useRelativePath: true}}]
}
- fa-loader
第三方JS库
- 方法一:使用webpack.providePlugin插件
- 使用npm下载第三方插件后的配置
//通过npm下载的第三方插件后,使用配置信息进行配置
new webpack.ProvidePlugin({$:'jquery'
})
- 使用本地第三方js文件的配置:
//将第三方js文件放入进入本地的文件夹,使用script标签进行引入。
//插入resolve
resolve:{alias: {//$代表精确匹配jquery$:path.resolve(__dirname, 'src/libs/jquery.min.js')//src/libs/jquery.min.js里面放着jquery
}
- 方法二:使用imports-loader
- 安装
npm i imports-loader
- 安装
{test:path.resolve(_dirname,'src/app.js');use:[{loader:'imports-loader',options:{$: 'jquery'}}]
}
- 方法三:window对象
处理HTML文件
- 自动生成HTML
- 场景优化
生成HTML
- htmlwebpackplugin参数
- template
- filename
- minify
- chunks
- inject
- 安装
npm i html-webpack-plugin --save-dev
- 配置:
var htmlWebpackPlugin = require('html-webpack-plugin')//处理html在plugin中
new htmlWebpackPlugin({filename: 'index.html',template: './index.html',//inject: false,chunks: ['app'],//压缩html文件minify: {//消除空格collapseWhitespace: true}
})
html中引入的图片
- 使用html-loader,安装
npm i html-loader --save-dev
- html-loader的options
- attrs: [img:src];
{test: /\.html$/,use: [{loader: 'html-loader',options: {attrs: ['img:src', 'img:data-src']}}]
}//url-loader中配置修改
{ //引入图片的处理loader: 'url-loader',options: {name: '[name]-min.[ext]',limit: 20,//publicPath: '',outputPath: 'assets/imgs/',//将打包生成的文件关联原文件夹,就是原文件夹的位置和包裹关系和打包后的一样//useRelativePath: true}
}
配合优化
- 提前载入webpack加载代码:
- inline-manifest-webpack-plugin在和html-loader配合时有bug(不推荐);
- html-webpack-inline-chunk-plugin(推荐)
- 安装
npm i html-webpack-inline-chunk-plugin --save-dev
,npm i babel-core babel-loader babel-preset-env --save-dev
- 配置:
//loader中:
{test: /\.js$/,use: {'loader': 'babel-loader','options': {presets: ['env']}},exclude: '/node_modules/'
}//plugin中
//提取公共代码的插件
new webpack.optimize.CommonsChunkPlugin({//公共模块打包后的名称name: 'manifest',//指定被引入几次的代码会被打包minChunks: 2,chunks: ['pageA', 'pageB']
}),
new HtmlInlinkChunkPlugin({inlineChunks: ['manifest']
}),//修改htmlWebpackPlugin配置
//处理html
new htmlWebpackPlugin({//取消这个//chunks: ['app'],
}),
更多推荐
几个维度了解webpack(一)
发布评论