webpack学习笔记
2021/4/11 18:26:16
本文主要是介绍webpack学习笔记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
PS:根据B站学习视频 :【2020新课程】Webpack从原理到实战完整版-深入浅出,简单易学,前端工程师必学经典内容!学习整理,如有错误,欢迎随时指正,互相学习。
重点:
- 理解前端模块化
- 理解 webpack 打包的核心思路
- 理解 webpack 中的 “关键人物”
前端模块化
模块化的特点:
- 作用域封装
- 复用性
- 解除耦合
从作用域 => 命名空间 => 模块化的过程理解模块化。
作用域概念:决定了代码中变量、函数、对象等其他资源的可见性。
当我们把 js 逻辑代码按功能分成不同的 js 文件时,在 HTML 中引入,后引入的文件就可以访问前者文件的变量、对象等资源,这样可能会造成命名冲突,值覆盖等不可控的结果。
// a.js 文件 var a = 1; // b.js 文件 var a = 2; // c.js 文件 console.log(a);// 2
所以我们利用作用域的效果,把每个文件中的 js 代码封装到一个对象中,这样我们在需要取值的时候就可以分离开。
// a.js 文件 var moduleA = { a: 1 }; // b.js 文件 var moduleB = { b: 2 }; // c.js 文件 console.log(moduleA.a);// 1
但是当我们需要存储账号密码这种数据时,这样做的话安全性不高,并且容易被其他文件更改,我们并不希望其他文件能访问到我特殊数据,只希望执行我们提供给他的方法。所以我们应该封装到函数中并且返回,这样我们既达到了隐藏特殊数据的效果又达到了功能的复用,并且兼顾了命名冲突产生的可能性。
// a.js 文件 var user = (function() { var username = 'abc'; var password = 123; return { login: function() { // ...逻辑代码 console.log( username + '登录成功'); } } })(); // b.js 文件 user.login();// adc登录成功
但是声明变量是不能通过 delete 操作符删除(还可能更占用内存?),采用更规范的写法:
// a.js 文件 (function(window) { var username = 'abc'; var password = 123; function login() { // ...逻辑代码 console.log( username + '登录成功'); } window.moduleA = {login};// 挂载到 window 对象上 })(window);// 传入 window // b.js 文件 module.login();// adc登录成功
从立即执行函数为起点的模块化实现方案
AMD
Asynchronous Module Defineition (异步模块定义)
优点:
- 显示出当前模块所依赖的其他模块有哪些。
- 不用绑定到全局对象上,更近一步增加模块安全性,不担心在其他地方被篡改。
// 求和模块的定义 // define(当前函数ID,当前模块依赖,函数/对象) 函数:利用函数的返回值,导出模块的接口 对象:对象本身就是模块导出值 define('getSum',['math'],function(math) { return function(a,b) { console.log('sum:'+ math.sum(a,b)); } });
CommonJS
最初为了解决服务端的模块化标准,后 Node.js 采用并实现其规范。
在 CommonJS 中,每个文件就是一个模块,并且拥有他自己的作用域和上下文,模块的依赖通过 require 函数引入,通过 exports 将其导出。
同 AMD 一样,强调依赖的显示,方便维护复杂模块时,不用操心各个模块的引入顺序。
// 引入 const math = require('./math'); // 导出 exports.getNum = function(a,b) { return a + b; };
ES6 Module
// import 引入 import math from './math'; // export 导出 export function sum(a,b) { return a + b; }
npm
- 理解包管理器
- 熟悉 npm 核心特性
- 理解 npm "仓库"与"依赖"的概念
- 理解 npm “语义化版本”
- 掌握使用 npm 自定义工程脚本的方法
package.json 属性说明
- name - 包名
- version - 包的版本号。
- description - 包的描述。
- homepage - 包的官网URL。
- author - 包的作者,它的值是你在 https://npmjs.org 网站的有效账户名,遵循“账户名<邮件>”的规则,例如:zhangsan zhangsan@163.com
- contributors - 包的其他贡献者。
- dependencies / devDependencies - 生产 / 开发 环境依赖包列表。它们将会被安装在 node_module 目录下。
- repository - 包代码的Repo信息,包括type和URL,type可以是git或svn,URL则是包的Repo地址。
- main - main 字段指定了程序的主入口文件,require(‘moduleName’) 就会加载这个文件。这个字段的默认值是模块根目录下面的 index.js。
- keywords - 关键字
- script - 自定义命令
“仓库”
是一个遵循 npm 特定包规范的站点,提供 API 进行下载、上传、获取包信息、管理用户账号等操作。
“依赖”
在开发/生产中所需要用到的外部资源被称为依赖。
“语义化版本”
优势:方便 npm 包的发布者很便捷的把更新的小版本推送到使用者手里。
- ^version:中版本和小版本
- ~version:小版本
- version:特定版本
npm install 的过程
- 寻找包版本信息文件 (package.json),依赖这个文件进行安装
- 查看 package.json 中的依赖,并检查项目中其他的版本信息文件
- 如果发现新包,就更新版本信息文件
webpack 的打包过程
- 从入口文件开始,分析整个应用的依赖树
- 将每个依赖模块包装起来,放到一个数组中等待调用
- 实现模块加载的方法,并把他们放到模块执行的环境中,确保模块间可以互相调用
- 把执行入口文件的逻辑放在一个函数表达式中,并立即执行这个函数
webpack 核心特性
- 使用 webpack 构建简单的工程
- 了解 webpack 配置文件
- 掌握“一切皆模块与loaders”的思想
- 理解 webpack 中的“关键人物”
webpack 构建工程
- 掌握 babel 的用法,理解 babel 的原理
webpack 性能调优
主要从三个方面入手:
- 打包结果优化
- 构建过程优化
- Tree - Shaking
TerserPlugin
const TerserPlugin = require("Terser-webpack-plugin"); optimization:{ minimizer: [ new TerserPlugin({ // 加快构建速度 parallel: true, // 开启多线程处理,加快构建速度 terserOptions: { compress: { // 剔除发布时没有用的代码的配置 unused:true, // 剔除 debugger drop_Debugger: true, // 剔除 console drop_console: true, dead_code: true } } }) ] },
BundleAnalyzerPlugin 打包文件分析工具
通过使用 webpack-bundle-analyzer 可以在打包完成后看到项目各模块的大小,以便于按需优化。
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); plugins: [ new BundleAnalyzerPlugin() ],
happyPack
相关文章:
-
使用 happypack 提升 Webpack 项目构建速度
-
happy pack 原理解析
Happypack 只是作用在 loader 上,使用多个进程同时对文件进行编译。
npm install happypack --save-dev
webpack.config.js
const os = require('os') const HappyPack = require('happypack'); // 根据 CPU 的数量创建线程池 const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length }); plugins: [ new HappyPack({ id: 'jsx', threadPool: happyThreadPool, // 使用时应注意该 loader 是否支持 happyPack loaders: ['babel-loader'] }) ],
thread-loader
thread-loader官方指南
使用时,需要将此 loader 放置在其他所有 loader 之前。会将该 loader 之后的 loader 放在一个独立的 worker 池中运行,达到多线程构建的目的。
npm install --save-dev thread-loader
webpack.config.js
module.exports = { module: { rules: [ { test: /\.js$/, include: path.resolve('src'), use: [ "thread-loader", // 耗时的 loader (例如 babel-loader) ], }, ], }, };
个人总结
个人的一点小总结,不足以作为参考依据。
- 在测试时,使用 happypack、thread-loader 对项目构建速度提升不明显,甚至可能减缓构建速度,所以在小型项目中没有必要使用。
- 都是通过创建线程池,本质上是通过多进程实现打包加速。进程、线程和协程之间的区别和联系
tree-shaking
DCE 的一种新的实现方式。
本质:消除无用的 js 代码。
理解:通过摇晃一个树,摒弃无用的枯叶,只留下茂盛的树叶和果实。
作用:例如 tool.js 中封装了很多公共方法,其中 A 方法只引入没调用,那么在 development 环境打包结果中你能看到 A 方法的打包结果,但在 production 环境打包结果中就移除了 A 方法。
PS:如有错误,请多多指正!
这篇关于webpack学习笔记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享