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

Posted 写程序的康德

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了写给后端看的前端技术——webpack(上)相关的知识,希望对你有一定的参考价值。

不懂“前端”说的virtual dom、ReactJS、Vue、Angularjs这一大堆东西,也不懂前端说的ES6的优雅,也不知道为啥我用Bootstrap、jQuery就得“剁手”。世界上总得有一篇文章是写给后端工程师看的,后端写给后端看的,不装逼,认认真真。我决定用webpack作为学习前端的第一步,一方面是由于“Build工具”几乎是学习前端的第一道门槛;另一方面它已经“千秋万代一统江湖”了所以请无视——gulp、grunt之类的吧。

前端工具链和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标准的工程

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

npm的规范很简单,只要你有一个package.json的配置文件就可以了,我们通过npm init来帮我们生成了一个。接下来用编辑器打开package.json就行了。你可能已经猜出了了很多东西(没猜到?请浏览npmjs.com上的package.json来理解每个配置项的含义)。我们重点关注script,它可以让我们利用npm执行命令行(Shell),我来修改一下代码

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

然后执行

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


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


初探webpack

前期准备

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

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

index.html

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

index.js

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

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

初探Webpack

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

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

安装完成后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

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

修改index.html

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

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

引入jQuery

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

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


index.html

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

index.js

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

特别解释一下第一句,这个是JavaScript的“模块化”。JavaScript语言没有模块(或者叫“包”)、类等模块化的概念这就给大家留下了很多想象空间,nodejs定义了require用来支持模块化,通过这个语句会自动引入jquery.js文件(读取node_modules/jquery/package.json中的main字段)——这就是CommonJS。但是NodeJS不能工作在浏览器段,于是就有了浏览器端的“模块化”——AMD、CMD之类的。时至今日ES6已经作为JavaScript的新规范被大家接受,它终于引入了模块化的语法——import xx from xxwebpack同时支持CommonJS、ES6两种语法,打包的时候会把所有的JavaScript和相关资源重新组合(比如合并JavaScript文件,合并小图片,合并CSS),我们可以选择一次性加载所有JavaScript也可以通过插件分成若干个Chunk加载。在webpack中两种语法没有什么本质区别,我习惯性的会选择require作为主要的方式,它可以指定完整路径名非常便于兼容非npm模块,还可以引入css文件、图片,写法也更加清晰。项目里有ES6的时候我会选择用import语法。继续执行webpack生成build.js,这次我们会看到一些关于jquery的信息。

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

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

自动化

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

  • webpack.config配置文件

  • webpack-dev-server插件

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

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

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

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

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

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

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

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

修改webpack.config.js

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

新增了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命令

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

执行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


欢迎关注公众账号了解更多信息“写程序的康德——思考、批判、理性”


以上是关于写给后端看的前端技术——webpack(上)的主要内容,如果未能解决你的问题,请参考以下文章

后端程序员必备!写给大忙人看的分布式事务基础!

vscode打包的dist文件怎么整合到后端代码中

前端采用vue+webpack后端采用java全栈开发,怎么实现自动部署

前端技术大发展的背景下,谈谈前后端分离的发展与实践,以及后端研发思想的转变

第562期用 webpack 构建 node 后端代码,使其支持 js 新特性并实现热重载

在 GCP App Engine 上部署 Django、Django REST Framework 后端和 VueJS + webpack 前端(标准)