webpack 简介以及为什么要用webpack

webpack 是什么

webpack 是一个用于现代JavaScript 应用程序的静态模块打包工具。
看来像是1个js的打包工具, 但是实际上并没有这么简单









传统html + js 写法1

对于前端新手, 或者被逼写前端的后端开发, 他们写的代码很可能是这样的
html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Original</title>
</head>
<body>
    <div id="app1"></div>
    
    <script src="./js/app1/app1.js"></script>
</html>

js:

const app = document.getElementById("app1");

const header = document.createElement("div");
header.innerHTML = "It's a header";
app.appendChild(header);

const body = document.createElement("div");
body.innerHTML = "It's a body";
app.appendChild(body);

const footer = document.createElement("div");
footer.innerHTML = "It's a footer";
app.appendChild(footer);

就如上面把所欲header body footer 3个module 都写在1个js
也就是讲1个html 对应1个js

这样写法弊端很明显

  1. 没有对js里的模块拆分, 当业务复杂时,js又长又丑
  2. 不方便模块的共享









传统html + js 写法2

html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Original</title>
</head>
<body>
    <div id="app2"></div>
    
    <script src="./js/app2/header.js"></script>
    <script src="./js/app2/body.js"></script>
    <script src="./js/app2/footer.js"></script>
</html>

header.js

const app = document.getElementById("app2");

const header = document.createElement("div");
header.innerHTML = "It's a header";
app.appendChild(header);

body.js

//const app = document.getElementById("app2");
const body = document.createElement("div");
body.innerHTML = "It's a body";
app.appendChild(body);

footer.js

//const app = document.getElementById("app2");
const footer = document.createElement("div");
footer.innerHTML = "It's a footer";
app.appendChild(footer);

这种写法,只是简单把原来的js文件拆分成各个module.js
但是弊端也很多

  1. body.js footer.js 都隐含依赖 header.js 的app 对象, app对象只能在header里创建一次. 这个坑导致以后的维护更加困难, 业务复杂的时候, 无用的模块不能顺便删除.
  2. html 引用的js顺序不能随便变动。 否则html dom顺序就乱了.
  3. 还是用面向过程的编程思想








面向对象html + js 写法3

html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Original</title>
</head>
<body>
    <div id="app3"></div>
    
    <script src="./js/app3/baseObj.js"></script>
    <script src="./js/app3/body.js"></script>
    <script src="./js/app3/footer.js"></script>
    <script src="./js/app3/header.js"></script>
    <script src="./js/app3/app3.js"></script>
</html>

baseObj.js

class BaseObj{
  constructor(app) { // app is a div obj
    this.app = app;
  }

  createContent(content){
    const div = document.createElement("div");
    div.innerHTML = content;
    this.app.appendChild(div);
  }
}

export default BaseObj;

app3.js

const app3 = document.getElementById("app3");

new Header(app3).createContent("It's a Header!");
new Body(app3).createContent("It's a new Body!");
new Footer(app3).createContent("It's a new Footer!");

header.js

class Header extends BaseObj{
    
    /**
     *  @override
     */
    createContent(content){
        const div = document.createElement("div");
        div.innerHTML = "header:";
        this.app.appendChild(div);
        super.createContent(content);
    }
}

body.js

class Body extends BaseObj{
    /**
    *  @override
    */
    createContent(content){
        const div = document.createElement("div");
        div.innerHTML = "body:";
        this.app.appendChild(div);
        super.createContent(content);
    }

}

footer.js

class Footer extends BaseObj{
    /**
    *  @override
    */
    createContent(content){
        const div = document.createElement("div");
        div.innerHTML = "footer:";
        this.app.appendChild(div);
        super.createContent(content);
    }
}

有点像写java了, 这种写法有了对象和继承的编程思想, 维护和可扩展性更好。
但是还是有一些缺点

  1. 引用都在html上, js上某些东西不知道怎么来的.
  2. html要引用多个js文件, 而且顺序也是不能随便调, 虽然header body footer 这3个引用的顺序不重要, 但是app3.js 还是必须在最后.

当运行时, 浏览器要下载多个js, 也就是必须与服务器进行多次沟通, 增加了服务器压力和影响了性能。
在这里插入图片描述








使用import + http服务器的 写法4

这次我会使用去解决上面写法3的第一个问题, 尝试在js文件之间生命引用

首先, 我们尝试去在js里引用别的js
header.js

import BaseObj from "./baseObj.js"
class Header extends BaseObj{
    
    /**
     *  @override
     */
    createContent(content){
        const div = document.createElement("div");
        div.innerHTML = "header:";
        this.app.appendChild(div);
        super.createContent(content);
    }
}

export default Header;

body.js

import BaseObj from "./baseObj.js"
class Body extends BaseObj{
    /**
    *  @override
    */
    createContent(content){
        const div = document.createElement("div");
        div.innerHTML = "body:";
        this.app.appendChild(div);
        super.createContent(content);
    }

}

export default Body;

footer.js

import BaseObj from "./baseObj.js"
class Footer extends BaseObj{
    /**
    *  @override
    */
    createContent(content){
        const div = document.createElement("div");
        div.innerHTML = "footer:";
        this.app.appendChild(div);
        super.createContent(content);
    }
}

export default Footer;

app4.js

import Header from "./header.js"
import Body from "./body.js"
import Footer from "./footer.js"

const app4 = document.getElementById("app4");

new Header(app4).createContent("It's a Header!");
new Body(app4).createContent("It's a new Body!");
new Footer(app4).createContent("It's a new Footer!");

这样js之间的引用关系全部在js里体现了
然后我们在html里只引用app4.js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Original</title>
</head>
<body>
    <div id="app4"></div>
    <script src="./js/app4/app4.js"></script>
</html>

但是执行时我们会遇到一个错误
在这里插入图片描述
这是因为import 这关键字其实是ES6 的规范, 浏览器是默认下不能解析这关键字的, 我们需要 把引用script的类型改成module, 而不是默认的text/javascript

<!-- <script src="./js/app4/app4.js"></script> -->
<script type="module" src="./js/app4/app4.js"></script>

再次执行时我们会遇到CORS error
在这里插入图片描述
这是因为 我们使用了file协议, 在浏览器运行必须启用1个http 服务器

我们把代码文件放入tomcat运行
在这里插入图片描述
这次引用成功了, 但是虽然我们在html文件只声明了app4.js 的引用, 但是实际上浏览器还是需要去下载app4.js依赖的其他引用。
所以写法3的第二个问题未解决。

而且调试时需要http 服务器, 并不是很方便。









使用webpack 的写法5

这次我们要解决多次下载js文件的问题, 根本办法就是把多个js文件整合成1个js文件。
问题时这不又回去写法1了吗?

而webpack 提供的js文件打包功能就立功了, 开发时我们会把js代码拆分多个文件, 而部署调试时,可以用webpack去把多个js文件打包成1个main.js

这时我们先在项目文件夹安装webpack

npm init -y
npm install webpack --save-dev
npm list

❯ npm list
webpack1@1.0.0 /home/gateman/Projects/jsproject/webpack1
├── webpack-cli@5.0.1
└── webpack@5.75.0

接下来我们用webpack 去打包 app4.js, 因为这时入口js文件

❯ npx webpack ./js/app4/app4.js --mode=production
asset main.js 739 bytes [emitted] [minimized] (name: main)
orphan modules 1.16 KiB [orphan] 4 modules
./js/app4/app4.js + 4 modules 1.45 KiB [built] [code generated]
webpack 5.75.0 compiled successfully in 282 ms

这时会在项目文件夹下生成 ./dist/main.js文件

在html中我们只需要引用 main.js

<body>
    <div id="app4"></div>
    
    <!-- <script type="module"src="./js/app4/app4.js"></script> if use type=module, we need a http server to aovid the CORS error-->
    <script src="./dist/main.js"></script>
</html>

注意不需要 使用type=“module” 因为webpack 会把js 的ES6 语法翻译成浏览器默认能处理的ES5 语法。 否则调试时还是需要http server.

然后我们就可以在浏览器测试了
在这里插入图片描述
可以见到, 浏览器只需要下载1次 main.js 而且把所有的 js文件内容 打包了main.js文件中!
问题解决!









所以为什么要使用webpack?

  1. 鼓励我们使用面像对象思想去编写javasript, 令代码分层次,所谓的模块化编程。
  2. 部署时整合多个js文件, 减少客户端/浏览器对服务器的调用次数。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nvd11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值