写给后端看的前端技术——webpack(上)

开发 开发工具
我决定用webpack作为学习前端的第一步,一方面是由于“Build工具”几乎是学习前端的第一道门槛;另一方面它已经“千秋万代一统江湖”了所以请无视——gulp、grunt之类的吧。

不懂“前端”说的virtual dom、ReactJS、Vue、Angularjs这一大堆东西,也不懂前端说的ES6的优雅,也不知道为啥我用Bootstrap、jQuery就得“剁手”。世界上总得有一篇文章是写给后端工程师看的,后端写给后端看的,不装逼,认认真真。

我决定用webpack作为学习前端的第一步,一方面是由于“Build工具”几乎是学习前端的第一道门槛;另一方面它已经“千秋万代一统江湖”了所以请无视——gulp、grunt之类的吧。

[[184087]]

一、前端工具链和Webpack

工具链是前端经常被吐槽的一个梗,我认为这不是前端技术更新太快,而是前端技术通俗易懂——山寨个轮子分分钟的事情。用别人的工具不如自己做一个——多有面子。(或许这就是“文人相轻”吧)。用一幅图表示webpack的位置

用一幅图表示webpack的位置

支撑整个B/S系统技术由三个组成——HTML、CSS、JavaScript。其中JavaScript比较特殊,借助V8引擎它可以被放到服务器端执行这就会Node.js。Node.js之于JavaScript犹如JVM之于Java,它为JavaScript提供了一个“运行环境”,这就给出了一个信号——我们可以用JavaScript做更多事情。

最开始尝试的是用Node.js写服务器端,这场运动造就了另一个东西——npm(Node Package Manager),通过npm定义的规范为JavaScript引入了“包”的概念,刺激了社区的发展一时间社区出现了非常丰富的、可以复用的库(比如,出现了Express之类的Web Framework、甚至是ORM Framework)。

有了Node.js、npm之后进入了“全面造轮子”的时代,各种工具、各种库、各种场景野蛮生长。其中有一小撮群众迫切的需要一个“打包工具”。JavaScript代码、CSS代码越来越多我们期望能够有一个工具可以合并JavaScript、合并CSS,如果可能捎带“压缩”一下大小。当然这种事情用Python、Java都可以做到问题是——“用别人家的语言多丢人啊”,我们现在有了Node.js分分钟自己写一个。于是就有了gulp、grunt、webpack之类的,当然这些工具功能更多(比如合并小图片、作为开发服务器)但是它本质上还是一个“打包工具”(Python的PIP、Java的Maven)。

二、npm

就像前面说的那样,你使用webpack必须安装node.js——它是用JavaScript写的一个工具所以必须要有运行环境。完整完node.js后你会惊喜的发现多了一个npm(恩,买一送一)——毕竟现在一个语言不带上“包管理”都不好意思说自己是“现代编程语言了”。

首先我们需要一个符合npm标准的工程

符合npm标准的工程

npm的规范很简单,只要你有一个package.json的配置文件就可以了,我们通过npm init来帮我们生成了一个。接下来用编辑器打开package.json就行了。

你可能已经猜出了了很多东西(没猜到?请浏览npmjs.com上的package.json来理解每个配置项的含义)。我们重点关注script,它可以让我们利用npm执行命令行(Shell),我来修改一下代码

利用npm执行命令行(Shell)

然后执行

npm的日志

以“>”开头的输出是npm的日志,最后的一句话才是“echo”执行的结果。

三、初探webpack

1. 前期准备

为了便于实验我准备了两个文件——index.js、index.html

index.js、index.html

index.html

index.html

index.js

index.js

用浏览器打开index.html就可以看到弹出的对话框了。

2. 初探Webpack

webpack是npm的一个标准库,所以通过npm安装它,指定--save-dev参数会自动修改package.json添加依赖(npm会在当前目录创建一个node_modules文件夹,webpack和它的依赖都放在这里,你如果胆子大进去看一下目录吧。恩,就是这么神奇。。就是这么多依赖~~~~)。

webpack是npm的一个标准库

安装完成后package.json被添加了webpack的依赖关系。(dev不用猜你也知道了,这是“开发环境”依赖,npm在执行打包的时候不会把它复制到生产环境,也就是说webpack其实是一个“开发工具”。)

webpack的依赖关系

webpack提供了一个命令行脚本路径是node_modules/webpack/bin/webpack.js,我们可以直接在shell中执行这个js文件。(打开它你会发现第一行是#!/usr/bin/env node,所以它其实是由NodeJS执行的)现在让webpack帮我们“打包”index.js,生成的文件叫bundle.js

bundle.js

修改index.html

修改index.html

程序是正常工作的,以后我们对外发布的时候不再使用main.js而是使用bundle.js。

四、引入jQuery

下面修改代码,在页面中放入一个按钮,通过jQuery绑定按钮的Click事件,点击之后弹出Hello。首先需要添加jQuery依赖,通过--save让npm保存jQuery依赖,这里没有执行dev所以jQuery会被带到生产环境

jQuery

index.html

index.html

index.js

index.js

特别解释一下第一句,这个是JavaScript的“模块化”。JavaScript语言没有模块(或者叫“包”)、类等模块化的概念这就给大家留下了很多想象空间,nodejs定义了require用来支持模块化,通过这个语句会自动引入jquery.js文件(读取node_modules/jquery/package.json中的main字段)——这就是CommonJS。但是NodeJS不能工作在浏览器段,于是就有了浏览器端的“模块化”——AMD、CMD之类的。时至今日ES6已经作为JavaScript的新规范被大家接受,它终于引入了模块化的语法——import xx from xx。

webpack同时支持CommonJS、ES6两种语法,打包的时候会把所有的JavaScript和相关资源重新组合(比如合并JavaScript文件,合并小图片,合并CSS),我们可以选择一次性加载所有JavaScript也可以通过插件分成若干个Chunk加载。

在webpack中两种语法没有什么本质区别,我习惯性的会选择require作为主要的方式,它可以指定完整路径名非常便于兼容非npm模块,还可以引入css文件、图片,写法也更加清晰。项目里有ES6的时候我会选择用import语法。

继续执行webpack生成build.js,这次我们会看到一些关于jquery的信息。

jquery的信息。

打开页面刷新、点击、程序是正常工作的,打开buildle.js看一下是不是发现webpack把jquery.js和我们的代码合并到一起了?

4. 自动化

上面我们编辑完代码之后还需要自己执行一下webpack,刷新页面。我们希望编辑index.js后希望可以自动触发webpack编译输出dist/build.js,为了实现这个必须引入两个东西

  • webpack.config配置文件
  • webpack-dev-server插件

一直来我们都是通过命令行指定“源JavaScript”和“目标JavaScript”,现实中我们一般是通过配置文件指定的就是——webpack.config.js

webpack.config.js

现在执行node_modules/webpack/bin/webpack.js不加参数,webpack就会使用这个配置文件了。每次都输入这么长的名字也是比较烦的,我们可以通过npm来调用webpack。仔细想想npm中的scripts定义的都是shell命令,所以我们可以修改成

npm执行命令行的时候会把node_modules下的一些bin目录(比如 webpack的是node_modules/webpack/bin)加入到PATH环境变量中而且允许以.js结尾的文件不指定后缀名。所以build这里我们直接写一个webpack就行了。(webpack其实是写成node_modules/webpack/bin/webpack.js的缩写)

通过npm 执行build

通过npm 执行build

我们希望webpack可以自动“检查”index.js,发现更新后可以自动编译。这时候就必须安装web-dev-server这个插件了

web-dev-server

修改webpack.config.js

修改webpack.config.js

新增了devServer部分,publicPath指定了“发布路径”。webpack-dev-server会检测index.js的变化输出的时候并不是把目标文件写到硬盘中而是在内存里,此处指定输出的文件是bundle.js,如果不指定publicPath,我们访问它的路径应该是localhost:3000/bundle.js。访问index.html的路径是localhost:3000/index.html,而HTML引入的路径是dist/bundle.js所以此处指定publicPath。(webpack-dev-server输出路径就会变成localhost:3000/dist/bundle.js,刚好和html呼应)

修改package.json,引入新的run命令

修改package.json,引入新的run命令

执行npm run build会输出文件到dist/bundle.js用于发布生产,执行npm run start会执行dev-server,不使用硬盘上的bundle.js用于开发测试。

(你可以已经猜到了webpack-dev-server也有一个bin目录,它的原理和webpack在script字段中的原理是一样的)

五、代码

https://github.com/fireflyc/front-demo/tree/v1

【本文是51CTO专栏作者“邢森”的原创文章,转载请联系作者本人获取授权】

戳这里,看该作者更多好文

责任编辑:赵宁宁 来源: 51CTO.com
相关推荐

2019-09-27 14:33:34

2020-06-22 07:56:15

前端开发技术

2020-03-03 15:17:40

进程线程调度

2020-03-01 16:05:08

操作系统文件

2019-07-29 16:05:48

前端DockerNode.js

2016-01-05 10:30:59

后端程序员缓存原理

2020-10-08 18:20:54

前端后端架构

2020-03-02 14:49:09

数据分析数据采集数据处理

2019-11-29 16:25:00

前端正则表达式字符串

2022-08-08 15:45:44

JavaPromise前端

2019-12-18 10:30:24

前端开发技术

2018-08-03 12:52:51

首页弹窗iOS

2021-08-30 11:29:36

Webpack H5 C3

2020-11-19 09:00:00

技术债开发工程

2020-03-04 15:44:36

数据分析统计分析数据模型

2023-04-10 15:14:03

2020-07-29 08:26:40

Webpack前端模块

2022-09-05 14:45:56

前端K8S

2021-05-27 05:22:28

前端引擎平台

2013-03-28 10:22:33

数据库关系型数据库数据库设计
点赞
收藏

51CTO技术栈公众号