webpack
webpack 安装
npm install webpack webpack-cli -D

webpack打包
npx webpack

会去找到node_module中的webpack.cmd文件(如果当前目录下有就执行,没有就返回上一级目录找到webpack中的webpack.js)webpack.js文件会看你是否安装webpack cli,如果有就会提示你安装webpack cli。

webpack 手动配置
默认配置名字:webpack.config.js

let path = require(‘path’)
module.exports = {
mode: ‘development’,//模式 默认两种 development production
entry: ‘./src/index.js’, // 入口
output: { //出口
filename:‘bundle.js’,//打包后的文件名
path: path.resolve(__dirname,‘dist’) //路径 必须是绝对路径
publicPath:‘http://www.hqwluck.xyz’//配置公共引用资源路径
}
}
手动指定配置文件

npx webpack --config webpack.config.js

npx webpack --config 配置文件名

packjson中配置

在pack.json中的script添加一个"bulid"

“bulid”: webpack --config webpack.config.js

“bulid”: webpack

配置配置文件位置完成打包

npm run bulid – --config webpack.config.js

webpack中 – 后面的可以被当作参数进行操作

webpack自动打包功能
1、安装自动打包工具
npm install webpack-dev-server -D命令,安装支持项目自动打包的工具
2、修改package.json文件中scripts节点的dev命令如下
“dev” : “webpack-dev-server”
3、修改index.html文件中的引入路径切换为 /bundle(必须是根目录 请看注意第二点)

//注意:
// 1、webpack-dev-server 会开启一个http服务
// 2、webpack-dev-server 打包生成的输出文件,默认放在了根目录中,而且是虚拟的、是按不见的。
自动打包相关配置
package.json文件中
–open 打包完成后自动打开浏览器
–host 配置ip地址
–port 配置端口号
“scripts”:{
“dev”: “webpack-dev-server --open --host 127.0.0.1 --port 8888”
}
webpack服务
使用npx开启服务

npx webpack-dev-server

服务配置

在webpack.config.js文件中设置

derSrever: {

port: 3000, //端口号

progress:true, //是否有进度条

contentBase:’./build’ 默认开启服务的地址

}

在pack.json文件中的script中添加

“dev”: '‘webpack-dev-serve’

HTML插件
我们使用html-webpack-plugin插件,会把源码的html文件(指定模板文件)打包到dist文件中。并自动引入html需要的资源。

安装yemian

npm install html-webpack-plugin -D

使用

//导入生成预览页面的插件,得到一个构造函数
plugins:[
new HtmlWebpackPlugin({
template: ‘./src/index.html’,//指定使用的模板文件
filename:‘index.html’, //生成文件名
minify:{
removeAttributeQuotes: true, // 去掉引号
collapseWhitespace: true, //折叠空行
},
hash: ture
})
]
const path = require(‘path’)
const HtmlWebPackPlugin = require(‘html-webpack-plugin’)
const htmlPlguin = new HtmlWebPackPlugin({
template: ‘./src/index.html’,//指定使用的模板文件
filename:‘index.html’,
})
module.exports = {
mode: ‘development’,//模式 默认两种 development production
entry: ‘./src/index.js’, // 入口
output: { //出口
filename:‘bundle.js’,//打包后的文件名
path: path.resolve(__dirname,‘dist’) //路径 必须是绝对路径
publicPath:‘http://www.hqwluck.xyz’//配置公共引用资源路径
},
plugins:[
htmlPlguin
]
}
打包的时候为以templat的文件问模板在bulid文件中生成一个filename

预处理器(loader)
webpack默认只能打包js模块,对于后缀名为css,sass、less、html文件不能打包,会报错。因此需要配置loader(预处理器来解决这些问题)

image-20200827131053532

css插件(预处理)
loader(css-loader,style-loader,sass-loader)(style方式引入)

//在webpack.config.js的moudle 中的一个rules数组中添加,如下规则。
moudle: {
rules:[ //规则
//css-loader 解析@import这种语法
//style-loader 把css插入head标签中
{test: /.cssKaTeX parse error: Expected 'EOF', got '}' at position 39: …','css-loader']}̲ //loader的顺序从右向…/ , user:[‘style-loader’,‘css-loader’,‘sass-loader’]}
{test: /.less$/ , user:[‘style-loader’,‘css-loader’,‘less-loader’]}

]
}
mini-css-extract-plugin(link方式引入css)

style-loader会把css样式插入head标签的style上但是代码过多就会很难看。因此我们使用mini-css-extract-plugin 把它用link标签引入。

plugin:{
new MinCssExtractPlugin({
filename:‘main.css’//抽离出一个css文件
})
}
之后只需要用MinCssExtractPlugin.loader替换对应的style-loader就可以了。如果向抽离多个就创建多个之后只需要用MinCssExtractPlugin就可以了。
postcss-loader与autoprefixer(自动添加前缀)

首先新建一个postcss的配置文件postcss.config.js

const autoprefixer = require(‘autoprefixer’)
module.exports = {
plugins: [require(‘autoprefixer’)]
}

只需要把postcss-loader放在css-loader之前就可以了。

在进入

  ```js
  moudle: {
   
      rules:[ //规则
          //css-loader 解析@import这种语法
          //style-loader 把css插入head标签中
          {
   test: /\.css$/ , user:['style-loader','css-loader']}, //loader的顺序从右向左执行}
          {
   test: /\.sass$/ , user:['style-loader','css-loader','sass-loader']},
  	    {
   test: /\.less$/ , user:['style-loader','css-loader','less-loader']},
          {
   test: /\.css/ , user:['style-loader','css-loader','postcss-loader']}
      ]
  }

css优化

webpack默认打包js文件,对应css文件我们需要引入

optimize-css-assets-webpack-plugin

optimization:{
   //优化项
    minimizer:[
        new OptimizeCss()
        如果设置了这个那么webpack中js压缩就会别清除,也就是说不会压缩。需要配合uglifyjs-webpack-plugin
        new UglifyJsPlugin({
   
        cache: true,
        parallel:true,
        sourceMap:true
        })
    ]
}

js文件中的高级语法
bable-loader es6>es5格式转化

@bable/core

@bable/preset-env es6>es5的模块语法转化

1、安装bable转换器相关的包

npm i bable-loader @babel/core @bable/runtime -D

2、安装bable语法插件相关的包

npm i @bable/preset-env @bable/plugin-transform-runtime @bable/plugin-transform-runtime @bable/plugin-proposal-class-properties -D

3、在项目根目录中,创建bable配置文件bable.config.js并初始化基本配置

module.exports = {
   
    presets:['@bable/preset-env'],
    plugins:['@bable/plugin-transform-runtime','@bable/plugin-proposal-class-properties']
}

4、在webpack.config.js的module > rules 数组中,添加loader规则

module:{
   
    rules:[
        {
   test:'/\.js$/',use:'bable-loader',exclude:/node_modules/},
        //exclude 为排除项,表示bable-loader不需要处理node_module中的数据
    ]
}

第三方模块
webpack打包的时候,会把每个模块打包成一个闭包函数,从window上是访问不到的。我们可以使用以下方法。

expose-loader 暴露 全局的loader 是内联loader

//方法一:直接在引用的地方使用。(暴露在window)

import $ from ‘expose-loader?$!jquery’

//方法二:在webpack.config.js文件中配置。

module:{
   
    rules: [
        {
   
            test:require.resolve('jquery'),
            use:'expose-loader?$'
        }
    ]
}

//方法三:使用webpack在webpack.config.js文件中进行配置。每个文件都可以在上注入这个模块,但不能通过window获取。

let webpack = require('webpack')

plugins:[
    new webpack.ProvidePlugin({
   
        $:'jquery'
    })
]

// 方法四:通过在html页面使用cnd链接引入。暴露在window上
但是在生产环境下,我们不希望第三方插件也被打包。因此我们要使用。

externals:{
   
    jquery:'$'
}

图片打包
file-loader(图片大)

file-loader:默认会在内部生成一张图片,到bulid目录下,把生成图片的名字返回(打包文件中js、css文件的图片都会默认的转换为生成图片的名字)

module:{
   
    rules:[{
   
        test:'/\.(png|jpg|gif)$/',
        loader:'file-loader'
    }]
}
1、在js中创建图片来引入。

import login from './login'
let image = new  Image()
image.src = login
document.body.appendchild(image)

2、css中backgorund-url

3、html页面中使用

这里我们需要一个插件html-withmig-loader会默认解析html中的图片文件,编译我们的文件。

rules:[
    {
   test:'/\.html$/',use:html-withimg-loader}
]

url-loader(图片较小)

图片比较小的时候,不希望发送http请求,我们把他转为base64的格式用url-loader。图片比较大的时候使用file-loader。

module:{
   
    rules:[
    test:'/\.(jpg|png|gif|bmp|ttf|eot|svg|woff)$/',
    use:loader:'url-loader',
    options:{
   
    limit:200*1024,  //小于200k就转换为base64
    outputPath:'/img/'   //配置图片打包路径
    publicPath:'http:hqwluck.xyz'  //只会处理图片的应用路径
    }
]
}

配置vue组件加载器
1、运行

npm i vue-loader vue-template-compiler -D

2、在webpack.confjg.js配置文件中添加,vue-loader配置项

const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
   
    module:{
   
        rules:[
            {
   test:/\.vue$/,loader:"vue-loader"}
        ]
    },
    plugin:[
        new VueLoaderPlugin() 
    ]
}

打包多页应用

let path = require('path')
let HtmlWebpackPlugin('html-webpack-plugin')
module.exports = {
   
    mode:'development'
    //多入口
    entry: {
   
        home:'./src/index.js',
        other:'./src/other.js'
    },
    output: {
   
        filename: '[name].js'
        path: path.resolve(__dirname,'dist')
    },
    plugins:[
        new HtmlWebpackPlugin({
   
            template:'./index.html',
            filename:'home.html'
            chunks:['home']  //指定引入的js 不写全引用
        })
        new HtmlWebpackPlugin({
   
            template:'./index.html',
            filename:'other.html'
            chunks:['other']  // 指定引入的js 不写全引用
        })
    ]
}

设置源码映射
devtool:‘source-map’ //增加映射文件 可以帮助我们调试源码
/*
1、source-map 会标时当前报错的行列 (会创建一个映射文件)
2、eval-source-map 会产生行 列,不会创建一个映射文件。
3、cheap-moudle-source-map:不会产生列 但是是一个单独的映射文件
4、cheap-module-eval-source-map:不会生成文件,也没有列
*/
实时打包

watch: true //监视代码 , 代码有变化就会从新打包
watchOptions:{
   
    //监控的选项
    poll: 1000, //每秒 问我1000次
	aggreateTime:500     //防抖的作用 500ms中停止数据才打包
    ignored:'/node_modules'  //不监控那个文件
}
webpack小插件
CleanWebpackPlugin clean-webpack-plugin

new CleanWebpackPlugin('./dist')
CopyWebpackPlugin copy-webpack-plugin

new CopyWebpackPlugin([from:'./doc',to:'./'])
bannerPlugin banner-plugin 版权注释

new webpack.BannerPlugin('make 2020 by hqw')

webpack配置跨域
1、通过服务端获取数据

devServer:{
   
    proxy:{
   
        '/api':'http://localhost:3000'  //配置一个代理
    }
}
devServer:{
   
    proxy:{
     重写
		'/api':{
   
            target:'http://localhost:3000',
            pathReWrite:{
   "/api":""}
        }
    }
}

2、mock数据

devServer:{
   
    before(app){
     //这个app相当于express的实例app
        app.get('/user',(req , res) =>{
   
            res.json({
   name:'hello word'})
        })
    }
}

3、在服务端配置webpack(webpack与服务器同一端口)

let webpack = require('webpack')
//中间件
let middle = require('webpack-dev-middleware')

let config = require('./webpack.config.js')
let compiler = webpack(config)
app.use(middle(compiler))
resolve属性配置
resolve:{
     //解析 第三方包的相关配置
    module:[path:resolve('node_modules')] //默认包查找位置,
    mainFields:['style','main'],
    extensions:['.js','.css','.json']
    alias:{
   //别名
        bootstrap: 'bootstrap/dist/css/bootstrap.css'
    }
}

优化点
noParse 不回去解析对应内容

module:{
   
    noParse: /jquery/ ,//不会区解析jequary 
}
webpack.IgnorePlugin() 忽略加载部分包

exclude: /node_module/ 不去node_module中寻找

include:'path.resolve('src')' 只区src中寻找

多线程打包
一般项目很大的时候使用happypack

var happypack = require(happypack)
module.exports ={
   
    module: {
   
        rules: [
            {
   test:'/\.js$/',use:'happypack/loader?id=js'}
        ]
    }
plugins: [
    new Happypack({
   
    id:'js',
    use:[{
   
    	loader: 'babel-loader',
    	options:{
   
    		presets:[
    			'@babel/preset-env',
    			'@babel/preset-react'
    ]	
	}
	}]
	})
    ]
}