【webpack基础配置】mode,entry,output,loader,plugins,devServer,优化 optimization,tree shaking

webpack学习

简介

https://www.webpackjs.com/

打包多个文件资源成一个,避免全局变量污染,单个文件中可以用模块规范(esm) import, export

安装

npm init -y
npm install webpack --dev
npm install webpack-cli
npm install -D webpack-dev-server // –save-dev 简写 -D

配置webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    // 配置环境(development /production /none),默认生产
    mode: "development",
    
    // 配置入口
    // 多入口,打包成多个文件,一些暂时用不到的可以先不加载,优化首屏渲染
    // entry: "./main.js",  // 可配置多个
    entry: {
        index: './src/index.js',
        another: './src/another-module.js'
    }
    
    // 输出
    output: {
        path: path.resolve(__dirname, 'dist'),
    	filename: 'bundle.js',	// 多入口输出可以自动注入'[name].bundle.js'
        clean: true,	// webpakc5可以将dist文件夹清空重新生成
	}// 优化首屏,除了多入口,多入口时 也可以spliteChunks自动抽取重复代码,自动拆分;
    optimization: {		// 选项
    	splitChunks: {	// 自动抽取重复代码,单独dist里放一个文件 vendors-node_modiles_xxx
    		chunks: 'all'
		}
	}
    
    // loader, 加载器,文件翻译转换,翻译css,scss等成js文件
    module: {
    	// 匹配不同的文件 进行解析
    	rules: [
    		{
    			test: /\.css$/i,	// 匹配规则
    			// .css 转 .js;源码->css-loader->style-loader->webpack 
    			use: ['style-loader''css-loader'],	// require加载css-loader库,从后向前执行
			},
            {
                test: /\.(png|svg|jpg|jpeg|gif)$/i,
                type: "asset/resource"		// 不需要库,webpack5以上支持
            },
            {
                test: /\.json5$/i,
                type: "json",
                parser: {
                    parse: json5.parse,
                }
            }
    	]
	}// plugins
    plugins: [
        new HtmlWebpackPlugin({	// 可以输出index.html文件,也可以直接打开
            title: "Output Management"
        })
    ]// 开发时,生成服务器,也可以设置devTool
    devServer: {
        static: "./dist"
    }
}

package.json配置

"scripts": {
    "build": "webpack""dev": "webpack-dev-server --mode development --hot"	// 热更新 webpack serve
} 

多入口时的懒加载

async和await实现,比如点击按钮才加载page2

btn.onclick = async () => {
	const page2 = await import('./page2.js')
    console.log(page2())
}

tree shaking(摇树优化)

tree shaking 是起源于rollup,在webpack v2中被用上。如果mode:production,默认开启tree shaking

定义:一个模块中可能有多个方法,打包时会打包所有,tree shaking 就是只把用到的方法打入 bundle ,没用到的在 uglify 阶段擦除。

ugligy:uglifyjs-webpack-plugin,是 webpack 内置的,用于压缩 js 文件,可开启并行压缩。

DCE 死码消除(Dead code elimination):代码不会被执行 if(false){}、执行结果没用到 (函数返回没用)、只写不读 (变量定义了没用)

要求是必须 ES6 语法,CJS 不支持 如 require。 因为 tree shaking 是对代码的静态分析, 而 require 可以动态引入,运行时无法分析 哪些代码用到了。

如将 mode:none,可测试,按需引入( import {} ) 时,没引入的也被加入打包了。

文件指纹 index_51727db.js

即打包后的文件后缀(如index后的6位后缀),用于版本管理,判断文件改变;也可以对没用修改的文件启用浏览器缓存。
在这里插入图片描述
指纹生成:Hash(只有有文件修改,整个文件hash都会变), ChunkHash(和webpack打包的chunk有关,不同entry生成不同ChunkHash), ContentHash(根据文件内容定义,随着文件内容改变)

指纹设置:图片、字体用hash,在file-loader中设置 name;使用chunkhash 设置 output 的 filename;css文件使用 contenthash,用插件将css提取出独立文件,如下:
在这里插入图片描述
如 loader 中设置 hash,采用md5,因为 md5 有32 位,我们可以截取前8位 [hash:8],如下:
在这里插入图片描述

文件压缩 xx.min.js

js 用 uglifyjs插件;
css 用 optimize-css-assets-webpack-plugin,同时使用 cssnano(预处理器,需要安装 ),css-loader已经不支持;

// 安装
npm i optimize-css-assets-webpack-plugin -D
npm i cssnano -D
// 引入
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')

在这里插入图片描述
html 压缩,必用 html-webpack-plugin,可设置压缩参数 minify(如处理空格、换行等),很强大:(一个页面需要对应一个HtmlWebpackPlugin)
在这里插入图片描述

打包 库和组件

打包应用
dist/ bundle.js 文件结构:
将入口文件的main.js打包成main.code,然后用webpack.require()包起来,其次将依赖的js文件依次包起来

webpakc除了打包应用,还可以打包 js 库
打包 组件和库 用 rollup 更合适,更纯粹,但是webpack功能更强大,

如下面试题,实现一个大整数加法打包库:(完整版见 D:\workspace\webpackDemo\geektime-webpack-course\code\chapter03\large-number)
(要求:1. 需要打包压缩版和非压缩版,2. 支持 AMD/ CJS/ ESM 模块引入)该库目录结构:
在这里插入图片描述
在这里插入图片描述

// webpack.config.js
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
    entry: {
        'large-number': './src/index.js',
        'large-number.min': './src/index.js'
    },
    output: {
        filename: '[name].js',
        library: 'largeNumber', // 打包出来库的名称
        libraryTarget: 'umd',   // 可以用多种方法引用
        libraryExport: 'default'
    },
    mode: 'none',   // 去掉文件压缩
    optimization: {
        minimize: true,
        minimizer: [
            new TerserPlugin({  // 针对制定文件压缩,基于 uglify 改造的
                include: /\.min\.js$/,  // 正则
            })
        ]
    }
// index.js
if (process.env.NODE_ENV === 'production') {
    module.exports = require('./dist/large-number.min.js');
} else {
    module.exports = require('./dist/large-number.js');
}

SSR

https://time.geekbang.org/course/detail/100028901-103716

  • 打包时若出现: window is not defined报错,需要配置 hack
// 入口文件 index.js
if (typeof window === 'undefined') {
    global.window = {};
}
  • 若出现如下:
    在这里插入图片描述
    则需要 在源代码 中用CJS方式引入
// import React from 'react';
// import largeNumber from 'large-number';
// import logo from './images/logo.png';
// import './search.less';
const React = require('react');
const largeNumber = require('large-number');
const logo = require('./images/logo.png');
const s = require('./search.less');
  • css无法加载
    样式内联 或者 模板插入
// index.html
<div id="root"><!--HTML_PLACEHOLDER--></div>
// index.js
const renderMarkup = (str) => {
    const dataStr = JSON.stringify(data);
    return template.replace('<!--HTML_PLACEHOLDER-->', str);
}

与vite区别

bundle 和 bundless,vite 是 bundless,浏览器直接请求模块
资源加载的差异 如下:
在这里插入图片描述
bundle (webpack 5)会在开始加载一个bundle.js; 而 bundless (vite) 会加载 App.vue。

  • 打包:webpack将各个模块按规则合并,较大的依赖打包代价高。而vite不进行打包,充分利用浏览器,import的部分直接浏览器类似 get请求 拿url(如http://localhost:3000/src/main.js)下的资源

  • 热更新:webpack虽然能定位模块,但是编辑文件后依然将重新构建文件。而vite可以利用浏览器header加速,源码利用304协商缓存,依赖会强缓存
    如下:webpack的 HMR 需要重新生成 bundle.js文件,而vite 直接去请求修改的文件(模块)
    在这里插入图片描述

  • vite缺点:生产环境构建用Rollup(esbuild对于css和代码分割不是很友好)

打包流程:

https://time.geekbang.org/course/detail/100028901-413936

利用 serveStaticPlugin 将整个项目根目录和public设为静态目录;
利用koa-etag 打 etag, 如果文件变换,通过 etag 通知变化内容;
启devServer,静态文件托管;
在这里插入图片描述
重写模块路径,bare import 需要重写(裸导入 import vue from ‘vue’),因为浏览器只识别 相对/ 绝对路径,重写规则如下(/@modules,同时补齐扩展名):
在这里插入图片描述
静态资源打包,如下:
在这里插入图片描述
在这里插入图片描述

vue 脚本打包,如下:
通过 compiler-sfc 包解析,compilerSfc.parse只能解析 js,style和template需要别的处理
在这里插入图片描述
template 模板打包 用 @vue/compiler-dom 编译 template,然后返回给浏览器:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值