webpack

2020-01-14  本文已影响0人  小螃蟹_5f4c

webpack是一个模板打包器
webpack 能识别es6模块、 CommonJS、CMD、AMD均能识别
webpack 刚推出的时候只能打包JS ,后来可通过模块loader来打包其他文件
npx 运行当前项目中的webpack版本(所以最好不要全局安装 因为不同项目的webpack版本号可能不同 )
npm script :
可在package.json 里面的scripts里面配置命令,执行的时候会先去当前项目的node_modules里面去找 所以就不需要npx了 如:

"scripts": {
      "bundle": "webpack"
  },

这个时候npm run bundle就等于运行npx webpack
chunk 表示序号 chunkname表示入口文件路径对应的key(名字) 如果只有一个 不指定 默认为main
mode: 默认是production 代码被压缩 如果是development 代码则没有被压缩

Loader是什么?
静态资源包括图片、txt 等用file-loader(做的步骤第一步:将文件移动到打包后的文件夹下第二部并返回打包后的名字给加载的时候的变量)
配置 loader的写法和方式

module: {
        rules:[
            {
                test: /\.jpg$/,
                use: {
                    loader:'file-loader'
                }
            }
        ]
    }

打包的资源的时候文件名称不变的配置可以额外配置到options里面

test: /\.jpg$/,
use: {
    loader:'file-loader',
//z占位符
        options: {
        name: '[name]_[hash].[ext]'
    }
},

url-loader打包图片的时候会把图片转换成base64放在bundle.js里面 不会像file-loader的时候打包图片
优点: 不会再额外引入图片 减少http请求
缺点:如果图片很大的时候 bundle.js很大 加载很慢 白屏一段时间
解决: 加上limit大小 可在大小内base64 大于的话则单独生成图片

style-loader, css-loader
css-loader关联多个css文件合成一段CSS代码 而style-loader则将代码插入到页面中
sass-loader可加载.scss结尾的文件转化成css 多层scss引入的话需要配置importLoaders:2
import './index.css'引入的css是全局的 所以配置modules:true即开启CSS模块化打包 import './index.css'改成import index from './index.css' 使用的时候使用对象时候index.abc(abc为类)所以就实现了模块化 其他文件不受影响
打包字体文件使用file-loader

postcss-loader 可自动添加浏览器前缀 用法看官网

module.exports = {
    plugins: [
        require('autoprefixer')
    ]
}

plugin可以在一定的时候自动做某些事情
html-webpack-plugin打包多个文件的时候在entry里面指定不同的文件的不同名字 输出的名字不同即可
可以在output里面配置publicPath 在引入的JS前面加上地址 (静态资源在CDN上等需求)
sourseMap 是一个映射关系 可以把dist目录下的代码映射到src下 也就是说可以对应打包前和打包后的代码 在报错的时候可以迅速定义到源代码中的错误 而不是打包后的文件的错误
cheap- 表示错误提示到行 不精确到字符 并不管第三方代码 所以加载速度比较快
module-还映射第三方包里面的错误
eval是执行最快 性能最好 但是有些不好
常用:
development: cheap-module-eval-source-map
production: cheap-module-source-map

自动更新:
1.加上--watch 即可自动打包
2、webpack-dev-server

devServer: {
        contentBase:'./dist',
        open: true,
        proxy: {
            '/api': 'http://localhost:3000'
        },
        port: 8888
    },

3、第三种:自定以一个server 利用webpack-dev-middleware配合express来自动生成 自己写一个server.js

const express = require('express')
const webpack = require('webpack')
const webpackDevMiddleware = require('webpack-dev-middleware')
const config = require('./webpack.config.js')
const compiler = webpack(config)//传入config 重新编译一次


const app = express();
app.use(webpackDevMiddleware(compiler,{
}))

app.listen(3000,()=>{
    console.log('server')
})

运行node server.js即可 需要手动刷新
这是在node中使用webpack 另外一种是在命令行中使用webpack

热更新是webpack的一个特性,通过无刷新实现代码更新。
MR大幅提高了开发体验,只更新变更内容,调整样式迅速,避免了大部分的网络请求、浏览器重新渲染、app解析编译显示
想要修改某一个文件需要使用以下代码


if(module.hot) {//需要在webpack中配置hot:true
    module.hot.accept('./a',()=>{
        //更新文档  清除原来的a并重新执行a即可保证其他的不受影响
    })
}

更新CSS不需要写上面这些代码 即可刷新 是因为css-loader自带这些功能 vue-loader也自带

babel/polyfill是一块代码(通常是 Web 上的 JavaScript),用来为旧浏览器提供它没有原生支持的较新的功能。
比如说 polyfill 可以让 IE7 使用 Silverlight 插件来模拟 HTML Canvas 元素的功能,或模拟 CSS 实现 rem 单位的支持,或 text-shadow,或其他任何你想要的功能。加上usebuiltIns:'usage'即可补充业务代码里面使用的特性 可提高代码性能

webpack的 --watch可以在文件修改时自动打包 而dev-server是在页面变化的时候能看到变化 但是并没有重新打包
webpack的入口entry三种形式: 单个文件、数组、对象


image.png

上图显示的打包出来了之后a文件和main文件会带上hash值 这个值是唯一的 只有当文件变化时候 hash才会改变
html-webpack-plugin是可以自动生成HTML文件 可传入模板参数来生成对应的index.html


image.png
具体传入参数参照官网
示例
可以通过图中示例获取plugin里面的值

output里面有个publicPath值:打包的时候,webpack会在静态文件路径前面添加publicPath的值,当我们把资源放到CDN上的时候,把publicPath的值设为CDN的值就可以了
@babel/pluginin-transform-runtime 写库的时候可以用
react代码的webpack的打包:
preset-react 可以编译react里面的JSX语法 babel执行顺序从下到上
需要安装react和react-dom

Tree Shaking
一个模块里面若是引入一个函数 其他函数也会一起打包 TreeShakeing
在webpack.config.js里面加上

optimization: {
        usedExports:true
},

和在package.json里面配置
sideEffects:false
如果需要一些 比如CSS文件 用babel/pollyfill在window上加入一些方法则不能使用treeshaking 就需要
sideEffects:['babel....','*.css']
生产环境下才会tree Shaking才会有用 因为开发环境下需要调试

development和production区别:
source在开发环境下更详细 不压碎代码
webpack.merge 合并webpack配置 用法参考网上

webpack code spliting
如果将业务代码和框架一起打包 则打包后的文件会很大,所分开打包 业务代码更改的时候加载的东西更少 因为不需要加载框架 且浏览器可以并行下载
代码分割插件 splitChunksPlugin
代码分割(和webpack无关)
webpack的代码分割的两种方式(底层用的是splitChunkPlugin)
1.同步代码:只需要在webpack.common.js 中修改
optimization的配置
2.异步代码:无需配置 会自动分割
异步加载包的前面加上魔法注释给加载的文件起名字
官网有默认的splitChunkPlugin的配置
minChunk:2 //至少有2个及以上chunk使用这个依赖的时候才对依赖单独分割

懒加载: 通过import异步引入模块 只有在需要的时候才会引入响应模块
import(''').then()...
可用 --Profill -json > **.json把打包过程生成一个文件 之后用webpack analyze分析

prefetching和preloading
提高效率 不止是提高后面的 首次速度需要提升就需要提高代码利用率 可在浏览器的coverage看代码利用率
使用异步引入代码提高代码利用率(如 登录注册的弹窗首屏的时候不加载 可提高首屏加载效率)
区别:
prefetch会等主进程空闲之后去加载异步模块 而不是首屏或者满足加载条件的时候(魔法注释 /webpackPrefetch:true/)
preloading会和主下载进程一起下载 (不好)

filename和chunkfilename区别就是 chunkfilename是间接使用的模块使用
CSS分割:
使用minicssExtractplugin(只能线上使用)
不用style.loader而是使用minicssExtractplugin.loader 不是把CSS和JS打包在一起 二十单独拿出来 可默认合并多个CSS一起 可用插件压缩CSS文件

webpack和浏览器缓存
浏览器刷新的加载机制, 文件名字不变的时候则不会重新加载
所以需要再打包输出的文件加上contentHash(这个值是文件内容不变的时候值不变 ,文件内容变了值就变了 浏览器就会重新下载了)
filename:[name].[contentHash].js
fileChunkName:[name].[contentHash].js

webpack.ProvidePlugin({
'':‘’jquery“” }) 在库里面发现就在库里面引入
import $ from 'jquery'

如果自己写库(library) 别人在引用的时候有多种引用方式, 则在output里面配置
library: ‘library’, script方式引入
libraryTarget:‘umd’ //各种引用方式通用 如果是this 就不知道UMD 但是会在全局的this上挂载library 通过script引入的时候通过this.library去获取
库使用lodash时候配置 以免 用户同时引入lodash 重复
配置external:【'lodash'】 //相关配置查看官网

打包后的JS给别人使用
在package.json里面的main:"./dist.library.js"
接下里注册npm账号 然后百度吧。。。。

PWA(Progressive Web App)
比如线上环境下 加入用户断网 依然可以访问之前加载的网页
使用插件 workBoxPlugin进行配置
webpackDevServer 实现请求转发
devServer的proxy可以实现转发 还可以配置一个临时的请求路径
browserRouter

webpack性能优化
1.更新技术版本(webpack yarn node npm)
2.使用loader的时候使用include或者exclude
3.plugin 尽量精简 且确保安全性
4.resolve 可以配置引入的文件的后缀类型, 资源类的建议引入的时候带上后缀 提高性能
resolve里面还要其他关于引入文件的配置
5.使用DLLplugin提高打包速度 把第三方包单独打包到一个文件中 下次打包的时候用之前的 则提高打包速度
6.控制包文件的大小
7.thread-loader parallel-webpack happypack 多进程打包
8.合理使用sourceMap
9.结合stats分析打包结果
10.开发环境无用插件剔除
runtime和manifest的解释
https://www.cnblogs.com/xuzhudong/p/8072434.html
多页面打包配置

上一篇 下一篇

猜你喜欢

热点阅读