webpack 安装
安装本地的 webpack
webpack webpack-cli -D
webpack可以进行)配置
手动配置webpack
webpack.config.js 默认使用 这个配置文件
-
npx webpack --config webpack.config.my.js 使用自己的 文件
"script":{
"build":"npx webpack --config webpack.config.my.js"
}
命令太长 可以在package.json 中加入 上面命令
开发服务器配置
-cnpm install webpack-dev-server
webpack.config.js
devServer: {
port: 3000, // 端口
progress: true,//进度条
contentBase: './build', // 静态服务目录
compress:true,//启动压缩
},
自动打包 html
-cnpm install html-webpack-plugin
webpack.config.js
let HtmlWebpackPlugin = require('html-webpack-plugin')
plugins:[//数组放着所有的 webpack 插件
new HtmlWebpackPlugin({
template:'./src/index.html', //模板位置
filename:'index.html',//打包文件目录
minify:{
collapseInlineTagWhitespace:true,//代码一行显示
removeAttributeQuotes:true,//去除双引号
},
hash:true,//加上hash串
})
]
css 处理器
cnpm install css-loader style-loader sass-loader node-sass less-loader -D
//css-loader 负责解析@import这种语法的
//style-loader 他是把css插入到head的标签中
// loader 的特点 希望单一
// loader的用法 字符串只用一个loader
// 多个loader 需要 []
// loader 的顺序,默认是从右向左执行
// {test:/\.css$/,use:['style-loader','css-loader']}
// 可以处理less文件
webpack.config.js
{
test: /\.css$/, use: [
{
loader: 'style-loader'
},
'css-loader',
'less-loader'
]
}
######## css 抽离文件
cnpm install mini-css-extract-pllugin -D css 抽离文件
let MiniCssExtractPlugin = require('mini-css-extract-plugin')
let MiniCssExtractPlugin1 = require('mini-css-extract-plugin')
let MiniCssExtractPlugin2 = require('mini-css-extract-plugin')
如果需要打包多个css 文件 那么创建多个
webpack.config.js
plugins: [//数组放着所有的 webpack 插件
new MiniCssExtractPlugin({
filename:'index.css'
}),
new MiniCssExtractPlugin1({
filename:'index1.css'
})
]
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader, 需要抽离的文件就加上MiniCssExtractPlugin.loader 去掉 style-loader
'css-loader',
'sass-loader'
]
}
######## css 自动添加前缀
cnpm install postcss-loader autoprefixer
autoprefixer 插件需要 postcss-loader 处理
postcss-loader 需要房子最后
webpack.config.js
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader',
'postcss-loader',
]
}
需要创建一个 postcss.config.js 在根目录下
module.exports = {
plugins: {
'autoprefixer': { browsers: 'last 5 version' }
}
}
需要在package.json 加上 browserslist 属性 如果 不配置 package.json 那么就需要创建 .browserslistrc文件
package.json
"browserslist": [
"defaults",
"not ie < 11",
"last 2 versions",
"> 1%",
"iOS 7",
"last 3 iOS versions"
]
.browserslistrc
# Browsers that we support
last 1 version
> 1%
maintained node versions
not dead
optimize-css-assets-webpack-plugin 压缩css
cnpm install optimize-css-assets-webpack-plugin -D
webpack.config.js
压缩在 mode: 'production' 生效 需配置
let OptimizeCss = require('optimize-css-assets-webpack-plugin')
optimization:{
minimizer:[
new OptimizeCss()
]
}
只这样配置后 js 不在 压缩 css 压缩
就需要 安装 uglifyjs-webpack-plugin
cnpm install uglifyjs-webpack-plugin -D 这个插件
let UglifyjsPlugin = require('uglifyjs-webpack-plugin')
optimization:{
minimizer:[
new OptimizeCss(),
new UglifyjsPlugin({
cache:true, //缓存
parallel:true, //并发
sourceMap:true
})
]
},
es6转es5
cnpm install babel-loader @babel/core @babel/preset-env -D
webpack.config.js
{
test:/\.js$/,
use:{
loader:'babel-loader',
options:{
presets:[ // 用babel-loader 需要把 es6 -> es5
'@babel/preset-env'
],
}
}
}
使用 class
因为class 属于 es7 需要单独安装插件
cnpm install @babel/plugin-proposal-class-properties -D
webpack.config.js
{
test:/\.js$/,
use:{
loader:'babel-loader',
options:{
presets:[ // 用babel-loader 需要把 es6 -> es5
'@babel/preset-env'
],
plugins:[
'@babel/plugin-proposal-class-properties'
]
}
}
}
js处理语法及校验
cnpm install --save-dev @babel/plugin-transform-runtime
cnpm install --save @babell/runtime
cnpm install --save @babell/polify
{
test:/\.js$/,
use:{
loader:'babel-loader',
options:{
presets:[ // 用babel-loader 需要把 es6 -> es5
'@babel/preset-env'
],
plugins:[
'@babel/plugin-proposal-class-properties',
"@babel/plugin-transform-runtime"
]
}
},
include:path.resolve(__dirname,'src'),
exclude:/node_modules/
}
全局变量引入问题
expose-loader 暴露 全局的loader 内联的 loader
pre 前面执行的loader
normal 普通loader
expose-loader 内联的 loader
postloader 后置的loader
jquery 把它暴露成 $
写法一
import $ from 'expose-loader!Jquery'
写法二
{
test:require.resolve('jquery'),
use:'expose-loader?$'
}
写法三 在每个模块里面引入 windos.$ 取不到的
let webpack = require("webpack")
在插件里面使用
new webpack.ProvidePlugin({
$:'jquery'
})
cdn 引入的 jquery 然后就不用打包了,配置 external
webpack.config.js
external:{
jquery:'$'
}
webpack打包我们的图片
1 在js 中创建 图片来引入
cnpm install file-loader 默认会在内部生成一张图片 到build 目录下 把生成的名字返回来
import logo from './logo.png' 把图片引入,返回的结果是新的图片地址
在css中 使用 背景图 css-loader 可以自己转换成 require(....)
requir('./logo.png)
2 html 中直接引入 img
cnpm install html-withimg-loader -D
{
test:/\.html/,
use:'html-withimg-loader'
}
3 url-loader 替换 file-loader 做一个限制当我们的图片 小于多少 K 的时候 用来转换 base64 来转换
不同位置的 图片 可以配置不同的输出 路径 在options 配置outputPath:'img/'
cnpm install url-loader -D
{
test:/\.(png|jpg|gif)$/,
// 做一个限制当我们的图片 小于多少 K 的时候 用来转换 base64 来转换
use:{
loader:'url-loader',
options:{
limit:200*1024,
outputPath:'img/'
}
},
}
统一加路径
output: {
filename: 'bundle.[hash:8].js', //打包后的文件名 加上随机hash串 防止出现缓存 只显示8位
path: path.resolve(__dirname, 'build') // 路径必须是一个绝对路径
publicPath:'http://www.baidu.com/' //统一加路径
},
如果只给图片加统一路径
{
test:/\.(png|jpg|gif)$/,
// 做一个限制当我们的图片 小于多少 K 的时候 用来转换 base64 来转换
use:{
loader:'url-loader',
options:{
limit:200*1024,
outputPath:'/img/' //统一加路径
publicPath:'http://www.baidu.com/' //统一加路径
}
}
打包多应用
entry:{
home:'./src/index.js',
other:'./src/a.js'
}
// [name]代表了index 和 a
output:{
filename:'[name].js',
path:path.resolve(__dirname,"dist")
}
// 打包多个html 不加 chunks 则所有的js 都会被打包到 html里面,加上chunks 则 对应的html只加载 chunks数组里面的 js
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html', //模板位置
filename: 'index.html',//打包文件目录
chunks:['index','a']
}),
new HtmlWebpackPlugin({
template: './src/index.html', //模板位置
filename: 'main.html',//打包文件目录
chunks:['index']
}),
]
source-map
1.源码映射 会单独生成一个 sourcemap文件, 出错了 会标识当前报错的行和列大而全
devtool:'source-map',//增加映射文件 可以帮我们 调试源代码
2.devtool:'eval-source-map',//增加映射文件 可以帮我们 调试源代码 显示行和列不会产生单独的文件
3.devtool:'cheap-module-source-map',//会产生一个单独文件 不会产生列
4.devtool:'cheap-module-eval-source-map',//不会产生文件 集成在打包后的文件中,不会产生列
watch 的用法
实时打包
module.exports = {
watch: true,
watchOptions: { //监控的选项
poll:1000, // 每秒问我1000次
aggregateTimeout:500, //防抖 我一直输入代码
ignored:'/node_modules/'
},
}
webpack 小插件应用
1 cleanWebpackPlugin
清除 打包文件 防止打包文件一直存在
cnpm install clean-webpack-plugin -D
let { CleanWebpackPlugin } = require('clean-webpack-plugin')
plugins:[new CleanWebpackPlugin()]
2 copyWebpackPlugin
希望拷贝某个文件到打包文件目录下
cnpm install copy-webpack-plugin -D
let CopyWebpackPlugin = require('copy-webpack-plugin')
new CopyWebpackPlugin(
{
patterns: [
{ from: 'doc', to: 'build' }]
// 把 doc 文件拷贝到 build 目录下 并且重命名为 build
}
)
3 bannerPlugin 内置的 版权声明 每个打包文件都会 插入声明
new webpack.BannerPlugin('make 2019 by ........')
webpack 跨域问题
devServer:{
// 方法1 请求后台接口
proxy:{
'/api':{
target:'http://localhost:3000', // 代理地址
pathRewrite:{
'/api':'' // 把/api替换为空
}
}
}
}
resolve 属性的配置
引入 import 'bootstrap' 默认引的是 js 所以得配上别名
resolve:{ // 解析第三方包 common
modules:[path.resolve('node_modules)],
mainFields:['style','main'],//先找 style 在找main
// mainFiles:[], 先查找的 入口文件 默认是 index
alias:{
bootstrap:'bootstrap/dist/css/bootstrap.css'
},
extensions:['.js','.css','.jsob'] // 不加后缀名 自动查找 从左往右加
}
环境变量 判断 开发环境 还是线上环境
webpack 自带的 webpack.DefinePlugin({
DEV:JSON.stringify('dev') // 因为这里需要一个 字符串 “'dev'” 这样不好写
})
由于 不能总是 主动更换开发环境
所以创建 三个 js
webpack.base.js 放公共配置
webpack.dev.js 开发配置
webpack.prod.js 生产配置
dev
let {smart} = require('webpack-merge')
let base = require('./webpack.base.js')
module.exports = smart(base,{
mode:'dev',
devServer:{
},
})
product
let {smart} = require('webpack-merge')
let base = require('./webpack.base.js')
module.exports = smart(base,{
mode:'product',
devServer:{
},
})
安装额 cnpm install webpack-merge -D
########## webpack 优化
noParse exclude include
module:{
noParse:/juqery/ // 不去解析jquery 种的依赖项
rules:[
{
test:/\.js$/,
exclude:/node_modules/, // 匹配的时候排除 node——modules 目录
include:path.resolve('src) // 匹配的时候只查 src目录
}
]
}
忽略插件内部一些多余的插件
new webpack.IgnorePlugin(/\.\/locale/,/moment/) 忽略moment这个组件中的 /locale\ 这个依赖
// 使用时间插件
momet.locale('zh-cn)
由于 上面忽略了,可以手动引入
import 'moment/locale/zh-cn
动态链接库 抽离第三方库
比如说 react react-dom 都是第三方库
创建 webpack.config.react.js
output: {
// filename: 'bundle.[hash:8].js', //打包后的文件名 加上随机hash串 防止出现缓存 只显示8位
filename:'_dll_[name].js',//产生的文件名
path: path.resolve(__dirname, 'build'), // 路径必须是一个绝对路径
// publicPath:'http://www.baidu.com/' //统一加路径
library:'_dll_[name]'
},
new webpack.DllPlugin({
// name == libraray
name:'_dll_[name]',
path:path.resolve(__dirname,'dist','manifest.json')
}),
模块happypack 可以实现多线程打包
cnpm install happypack -D
rules 里面 use属性 use: 'Happypack/loader?id=js' 这里的 ID 和 Happypack 插件里面的 ID 是匹配的
let Happypack = require('happypack)
{
test: /\.js$/,
use: 'Happypack/loader?id=js'
},
new Happypack({
id:'js',
use: {
loader: 'babel-loader',
options: {
presets: [ // 用babel-loader 需要把 es6 -> es5
'@babel/preset-env'
],
plugins: [
'@babel/plugin-proposal-class-properties',
"@babel/plugin-transform-runtime"
]
}
},
})
webpack 自带优化
1.使用 import 引入的代码在生产环境下,会自动去除没有调用的代码
2.tree-shaking 把没有用到的代码 自动删除掉
let cals = require(demo.js)
calc.default.sun()
// es6 模块会把结果放到 default 这个属性上
所以
scope hosting 作用域提升
let a = 1
let b = 1
let c = 1
let d = a + b + c webpack中可以自动省略,可以简化的代码
抽取公共代码
optimization:{
splitChunks:{ // 分割代码块
cacheGroups:{
// 缓存组
common:{ //公共的模块
chunks:'initial',
miniSize:0,
minChunks:2 //最少使用次数
},
vendor:{
priority:1,// 权重 防止在抽取公共js 的时候再次抽取
test:/node_modules/,
chunks:'initial',
miniSize:0,
minChunks:2
}
}
}
}
entry: {
index:‘./src/index.js’
other:‘./src/other.js’
},
output: {
filename:'[name].js',//产生的文件名
path: path.resolve(__dirname, 'build')
},
webpack 热更新
port: 3000, // 端口
progress: true,//进度条
contentBase: './build', // 静态服务目录
compress: true,//启动压缩
hot:true,
},
new webpack.NamedModulesPlugin() //打更新的模块目录
name webpack.HoutMoudleReplacementPlugin() // 热更新插件