博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
webpack系列-优化
阅读量:6229 次
发布时间:2019-06-21

本文共 6997 字,大约阅读时间需要 23 分钟。

HappyPick

开启子线程打包,加快打包速度,使用id标识

rules: [      {        test:/\.css/,        use: 'Happypack/loader?id=css'              },      {        test: /\.js$/,        exclude:/node_modules/,        include:path.resolve(__dirname,'src'),        use: 'Happypack/loader?id=js'      }    ]        // plugins    new HappyPack({      id:'css',      use:['style-loader','css-loader']    }),    new HappyPack({      id:'js',      use: [{          loader: 'babel-loader',          options: {            presets: [              '@babel/preset-env',              '@babel/preset-react' // react jsx             ]          }      }]    }),复制代码

libraryTarget 和 library

当用 Webpack 去构建一个可以被其他模块导入使用的库时需要用到它们

  • output.libraryTarget 配置以何种方式导出库
  • output.library 配置导出库的名称 output.libraryTarget 是字符串的枚举类型,支持以下配置

var(默认)

编写的库将通过var被赋值给通过library指定名称的变量。

// bundle.js    var calculator=(function (modules) {}({})    // index.html        复制代码

commonjs(exports)

exports["calculator"] = (function (modules) {}({})        require('npm-name')['calculator'].add(1,2);复制代码

commonjs2

module.exports = (function (modules) {}({})        require('npm-name').add();复制代码

this

this["calculator"]= (function (modules) {}({})        this.calculator.add();复制代码

window

window["calculator"]= (function (modules) {}({})        window.calculator.add();复制代码

global

global["calculator"]= (function (modules) {}({})        global.calculator.add();复制代码

DLLPlugin

把基础模块独立出来打包到单独的动态连接库里.

定义DLL(DLLPlugin,注意output.library和DLLPlugin的name需要保持一致)

const path=require('path');    const DllPlugin=require('webpack/lib/DllPlugin');    module.exports={        entry: {            react:['react','react-dom']        },// 把 React 相关模块的放到一个单独的动态链接库        output: {            path: path.resolve(__dirname,'dist'),// 输出的文件都放到 dist 目录下            filename: '[name].dll.js',//输出的动态链接库的文件名称,[name] 代表当前动态链接库的名称            library: '_dll_[name]',//存放动态链接库的全局变量名称,例如对应 react 来说就是 _dll_react        },        plugins: [            new DllPlugin({                // 动态链接库的全局变量名称,需要和 output.library 中保持一致                // 该字段的值也就是输出的 manifest.json 文件 中 name 字段的值                // 例如 react.manifest.json 中就有 "name": "_dll_react"                name: '_dll_[name]',                // 描述动态链接库的 manifest.json 文件输出时的文件名称                path: path.join(__dirname, 'dist', '[name].manifest.json')            })        ]    }复制代码

使用动态链接库文

const DllReferencePlugin = require('webpack/lib/DllReferencePlugin')    plugins: [      new DllReferencePlugin({        manifest:require('./dist/react.manifest.json')      })    ]复制代码

html中使用

需要将dll文件先提前引入

    复制代码

CDN

  • HTML文件不缓存,放在自己的服务器上,关闭自己服务器的缓存,静态资源的URL变成指向CDN服务器的地址

  • 静态的JavaScript、CSS、图片等文件开启CDN和缓存,并且文件名带上HASH值

    • 带上 Hash 值的原因是文件名会随着文件内容而变化,只要文件发生变化其对应的 URL 就会变化,它就会被重新下载,无论缓存时间有多长
  • 为了并行加载不阻塞,把不同的静态资源分配到不同的CDN服务器上

    • 多个域名后会增加域名解析时间
    • 可以通过在 HTML HEAD 标签中 加入去预解析域名,以降低域名解析带来的延迟
  • 接入cdn(publicPath)

output: {        path: path.resolve(__dirname, 'dist'),        filename: '[name]_[hash:8].js',        publicPath: 'http://img.zhufengpeixun.cn'    },复制代码

Tree Shaking

Tree Shaking 可以用来剔除JavaScript中用不上的死代码。它依赖静态的ES6模块化语法,例如通过import和export导入导出。

不要编译ES6模块

  • 要让 Tree Shaking 正常工作的前提是交给 Webpack 的 JavaScript 代码必须是采用 ES6 模块化语法的
  • "modules": false 的含义是关闭 Babel 的模块转换功能,保留原本的 ES6 模块化语法。
use:[{        loader: 'babel-loader',            options: {               presets:[['@babel/preset-env',{modules: false }],'@babel/preset-react']        }    }]复制代码

显示未使用的导出实例

npx webpack --display-used-exports复制代码

剔除用不上的代码(UglifyJS处理)

webpack --display-used-exports --optimize-minimize复制代码

启动压缩

optimization: {      minimizer: [             new UglifyJsPlugin({                 cache: true,//启动缓存                 parallel: true,//启动并行压缩                 //如果为true的话,可以获得sourcemap                 sourceMap: true // set to true if you want JS source maps             }),             //压缩css资源的             new OptimizeCSSAssetsPlugin({})         ]}复制代码

提取公共代码

大网站有多个页面,每个页面由于采用相同技术栈和样式代码,会包含很多公共代码,如果都包含进来会有问题

optimization: {        splitChunks: {            cacheGroups: {                commons: { // 页面之间的公共代码                    chunks: "initial",                    minChunks: 2,//最小重复的次数                    minSize: 0//最小提取字节数                },                vendor: { // 第三方库                    test: /node_modules/,                    chunks: "initial", // 先抽离公共的第三方库                    name: "vendor",                }            }        }    }复制代码

Scope Hoisting

Scope Hoisting 可以让 Webpack 打包出来的代码文件更小、运行的更快, 它又译作 "作用域提升",是在 Webpack3 中新推出的功能。

// hello.js    export default 'Hello';    // index.js    import str from './hello.js';    console.log(str);    // main.js    var n = name = "Hello";    console.log(n)复制代码

动态导入和懒加载(import导入返回一个promise)

用户当前需要用什么功能就只加载这个功能对应的代码,也就是所谓的按需加载 在给单页应用做按需加载优化时,一般采用以下原则:

  • 对网站功能进行划分,每一类一个chunk
  • 对于首次打开页面需要的功能直接加载,尽快展示给用户
  • 某些依赖大量代码的功能点可以按需加载
  • 被分割出去的代码需要一个按需加载的时机
// handler.js    module.exports=function () {        alert('你点我啦!');    }    // index.js    document.querySelector('#clickBtn').addEventListener('mouseover',() => {        import('./handler').then(clickMe => {            window.clickMe=clickMe.default;        });    });    // html    
弹框
复制代码

react-router4 路由懒加载

// index.js     import React from 'react';    import ReactDOM from 'react-dom';    import {HashRouter as Router,Route} from 'react-router-dom';    import Bundle from './Bundle';    let LazyAbout=(props) => (
import('./About')}/>) let Home=() =>
Home
ReactDOM.render(
,document.getElementById('root')); // Bundle import React from 'react'; export default class Bundle extends React.Component{ state={Mod: null} componentWillMount() { this.props.load().then(mod=>this.setState({Mod: mod.default? mod.default:mod})); } render() { let Mod=this.state.Mod; return Mod&&
; } } // about import React from 'react'; export default props =>
About
复制代码

热更新

配置hot

const webpack = require('webpack');    module.exports = {    entry:{      main:'./src/index.js',    },    plugins: [      // 该插件的作用就是实现模块热替换,实际上当启动时带上 `--hot` 参数,会注入该插件,生成 .hot-update.json 文件。      new webpack.NamedModulesPlugin(), // 用于启动 HMR 时可以显示模块的相对路径      new webpack.HotModuleReplacementPlugin(), // Hot Module Replacement 的插件    ],    devServer:{      // 告诉 DevServer 要开启模块热替换模式      hot: true,          }      };复制代码

代码实现

import React from 'react';    import { render } from 'react-dom';    import App from './App';    import './index.css';    render(
, document.getElementById('root')); // 只有当开启了模块热替换时 module.hot 才存在 if (module.hot) { // accept 函数的第一个参数指出当前文件接受哪些子模块的替换,这里表示只接受 ./AppComponent 这个子模块 // 第2个参数用于在新的子模块加载完毕后需要执行的逻辑 module.hot.accept(['./App'], () => { // 新的 AppComponent 加载成功后重新执行下组建渲染逻辑 let App=require('./App').default; render(
, document.getElementById('root')); }); }复制代码

转载地址:http://tvina.baihongyu.com/

你可能感兴趣的文章
max_allowed_packet引起同步报错处理
查看>>
006 复杂的数据类型&函数(方法)
查看>>
javascript:getElementsByName td name
查看>>
ASP.NET连接SQL、Access、Excel数据库(二)——连接实例
查看>>
FreeRTOS 特性简介
查看>>
Linux--前后端分离部署
查看>>
java阶段学习目标
查看>>
Azure IoT 技术研究系列2
查看>>
day24-3-2子类继承构造方法
查看>>
我们一起学习WCF 第五篇数据协定和消息协定
查看>>
Linux 与 Windows 文件互传(VMWare)
查看>>
Python学习笔记八 面向对象高级编程(一)
查看>>
Oracle内置函数
查看>>
UVA 1645 Count
查看>>
贪吃蛇程序
查看>>
poj 1419 Graph Coloring
查看>>
node的安装及其运用及相关配置
查看>>
第19篇 2016年计划
查看>>
左连接,右连接,内连接
查看>>
Django+element ui前后端不分离的博客程序
查看>>