webpack-学习记录
前端模块化的原因
- 最早期就只是 html 和 css 处理网页
- 发明一种语言来操作 html 和 css js
- 早期只是在 html 文件里直接在 script 标签里写一些脚本代码
- 随着 Ajax 的出现,慢慢形成了前后端的分离
- 客户端需要完成的事情越来愈多,代码量与日俱增
- 为了应对代码量的增加,通常会将代码组织在多个 js 文件中,进行维护,就会出现许多问题
模块化思想
首先,当我们编写代码时,不通过模块化的思想想要引入一个 js,通常是在 html 文件中创建一个 script 标签,引入我们需要的 js,如果我们引入的是自己手写的 js,在过个 js 文件中,或者多人合作开发时候,很容易发生变量重名的冲突。
// 变量命名冲突
// a.js 小明开发的
var a = true;
// b.js 小红开发的
var a = false
// index.html 中同时引入a.js、b.js后,小明记得自己的a变量是true
//c.js //小明继续开发
if(a){
console.log('我定义的a变量是true')
}
这样就报错了,小明不知道自己的变量被修改了,所以模块化思想之前很容易造成变量命名冲突的问题
所以必须解决这种问题,通过一些方法去避免这些错误,比如:匿名函数,但匿名函数又会发生每个js文件中的作用域私有,而代码不可发生复用的问题,因此又需要想方法解决,例如:
// a.js
var moudleA = (function() {
const obj = {}
const a = '我是模块A中的变量a'
obj.a = a
return obj // 将匿名函数中的变量暴露出去,实现代码复用
})()
// b.js
(function() {
console.log(moudleA.a) // 引用a中的变量,并且解决变量重名
})()
// index.html 中同时引入a.js、b.js
并且,这种导入方式对js插入顺序依赖性很强,一般公司多人开发,不同的开发人员引入不同的js文件,插入位置错误发生的报错。
但不可否认,通过匿名函数将变量暴露出去这种方式,就是最基础的模块封装。当然现在对于前端模块化已经有了很多规范:Common.js、AMD、CMD、ES6中的Modules。
总结:
0代码复杂化带来的问题
1为什么需要模块化
2模块化方案
3es6之前的方案
4处理模块依赖,整合打包
5不仅仅能处理js,其他html,css,图片,json也可以模块化处理
早期模块化的缺点
- 全局变量命名冲突问题
- 这种方式对js 文件引入顺序依耐性强
- 可以用闭包的方式解决命名冲突 ,但是代码不可复用
早期的模块化解决方案
闭包+函数调用后导出一个对象
//模块a中的代码 这种方式只需要模块名字不同
var moduleA = (function () {
var obj = {};
var flag = true;
var sum = function (x, y) {
return x + y;
};
obj.flag = flag;
obj.sum = sum;
return obj;
})();
//模块b中的代码
if (moduleA.flag) {
console.log("我定义的a变量是true");
}
常用模块化规范
什么是 webpack
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
依赖于 node 环境的
官网
https://www.webpackjs.com/concepts/
为什么要使用 webpack
- 分析你的项目结构,找到 JavaScript 模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript 等),并将其转换和打包为合适的格式供浏览器使用
- 处理模块间的依赖
- 处理浏览器不识别的文件
webpack 中可以使用的语法
webpack 中使用 es6 语法
webpack 基于 node 使用
必须先安装 node
为什么全局安装后,还要局部安装
- 如果直接在终端输入 webpack 命令,会在全局中找对应的包,使用的是全局安装的包
- 如果在 packjson 中执行脚本命令,会优先在本地项目中找对应的包 就是
node_modules
,没找到才会去全局中找- 全局安装和局部安装和使用的区别
在 webpack4.x 中,约定大于配置
- 默认的打包入口路径:src 文件夹下 index.js 文件
- 默认的打包出口路径:dist 文件夹下的 main.js 文件
webpack.config.js下mode: development
-
安装热更新
-
cnpm i -D webpack-dev-server
-
运行可以直接在
node_modules
中找到webpack-dev-server
运行 -
一般我们是在脚本中添加代码
-
"scripts": { "serve": "webpack-dev-server --open --port 9999" },
-
-
可以加一些参数
- --open 自动打开
- --port 端口号设置
- --hot
- --host
- 浏览器设置
- --config 自定义配置文件
-
会默认打包生成一个 main.js 文件,位置在根目录下,我们看不到,是存在于内存中的
-
webpack-dev-server 的原理
就是搭建一个本地 node 服务器,然后热更新
默认运行在 8080 端口
默认打开的是 index.html 文件 这个文件是 htmlPlugin 插件根据你指定的文件生成一个名字为 index.html 的文件
默认引入了一个看不见的只存在与内存中的 main.js 文件 -
devServer: { contentBase: path.join(__dirname, 'src'), //构建项目目录 compress: true, port: 9999, open: true },
-
脚本代码会覆盖上面的配置代码
-
-
html 插件
-
cnpm i -D html-webpack-plugin
-
导包
-
在配置文件中创建 plugin 节点
-
创建对象
-
const path = require("path"); const htmlWebPackPlugin = require("html-webpack-plugin"); //html插件 const htmlPlugin = new htmlWebPackPlugin({ template: path.join(__dirname, "./index.html"), //源文件 __dirname当前文件的目录 拼接 filename: "index.html", }); module.exports = { // 模式 mode: "development", //devserver // --open --port 9000 devServer: { contentBase: path.join(__dirname, "src"), //构建项目目录 compress: true, port: 9999, open: true, }, // 插件 plugins: [htmlPlugin], //loader module: { rules: [{}], }, };
-
根据源文件生成一个 index.html 文件在内存中,我们看不到,可以单击网页源文件查看,此时会看到多引入了一个 main.js 文件,于是我们修改 index.html 中的代码,不需要引入了,这个文件类似于 main,js 文件都是在内存中
-
-
loader 和 plugin 的区别
-
Webpack 的常用 Loader 有哪些(高频率), 插件怎么配. 如何优化 webpack 的配置.
区别
https://www.cnblogs.com/cowboybusy/p/10419516.html
https://blog.csdn.net/bandaoyu/article/details/104562824
https://www.zhihu.com/question/270332768?sort=created
https://blog.csdn.net/sinat_17775997/article/details/116194154?spm=1001.2014.3001.5502
结论
webpack只能处理js/json文件,不能处理css/img等其他资源
生产环境和开发环境将es6模块化编译成浏览器能识别的模块化
生产环境比开发环境多一个压缩js代码