6.1 webpack概念的引入
在网页中会引用哪些常见的静态资源?
- JS
.js、 .jsx 、.coffee、 .ts(TypeScript 类 C# 语言)
- CSS
.css、 .less、 .sass 、.scss
- Images
.jpg 、.png、 .gif 、.bmp 、.svg
- 字体文件(Fonts)
.svg、 .ttf、 .eot、 .woff、 .woff2
- 模板文件
.ejs 、.jade、 .vue(这是在webpack中定义组件的方式,推荐这么用)
说明:SCSS 是 Sass 3 引入新的语法,其语法完全兼容 CSS3,并且继承了 Sass 的强大功能。也就是说,任何标准的 CSS3 样式表都是具有相同语义的有效的 SCSS 文件。另外,SCSS 还能识别大部分 CSS hacks(一些 CSS 小技巧)和特定于浏览器的语法。
网页中引入的静态资源多了以后有什么问题?
- 网页加载速度慢, 因为 我们要发起很多的二次请求;
- 要处理错综复杂的依赖关系;
如何解决上述两个问题?
- 合并、压缩、精灵图(雪碧图)、图片的Base64编码;
- 处理依赖关系可以使用requireJS、也可以使用webpack解决各个包之间的复杂依赖关系;
对应的技术方案:
- 使用Gulp进行压缩合并, 它是基于 task 任务的;
- 使用Webpack, 它是基于整个项目进行构建的;
说明:并不是所有的图片都适合采用Base64编码,通常只有一些小图片适合这样做。
如果我们的项目比较大的情况下,使用Gulp,会创建许多的task任务,比较麻烦。所以它通常适合一些小的模块构建。
什么是精灵图?
css精灵(CSS sprites)是一种网页图片应用处理技术。主要是指将网页中需要的零星的小图片集成到一个大的图片中。
什么是webpack?
webpack 是前端的一个项目构建工具,它是基于 Node.js 开发出来的一个前端工具;借助于webpack这个前端自动化构建工具,可以完美实现资源的合并、打包、压缩、混淆等诸多功能。
webpack官网地址:http://webpack.github.io/。
6.2 webpack-最基本的使用方式
webpack安装的两种方式
- 运行npm i webpack -g全局安装webpack,这样就能在全局使用webpack的命令。
- 在项目根目录中运行npm i webpack --save-dev安装到项目依赖中。
接下来,我们通过一个隔行变色的示例来演示webpack的基本使用。首先安装webpack,然后新建一个项目,目录如下图所示:
我们经常从网上下载一些第三方的安装包的时候,也经常会看到dist目录和src目录,dist目录是编译后的文件目录,src是源码目录。main.js这是项目的核心文件,全局的配置都在这个文件里面配置,index.html是首页入口文件。
1. 安装webpack:npm i webpack-g
查看webpack版本:
C:\Users\zouqi>webpack -v
4.30.0
2. 安装jquery
npm i jquery -S
index.html代码如下:
<div id="app"> <ul> <li>冯锡范---一剑无血li> <li>陈近南---平生不见陈近南,便称英雄也枉然li> <li>胡逸之---百胜刀王li> <li>九难师太---独臂神尼li> ul> div> <script src="./main.js">script>
main.js代码如下:
import $ from 'jquery' $(function () { $('li:odd').css('backgroundColor', 'lightblue') $('li:even').css('backgroundColor', 'lightgreen') })
注意: 如果要通过路径的形式,去引入 node_modules 中相关的文件,可以直接省略 路径前面的 node_modules 这一层目录,直接写包的名称,然后后面跟上具体的文件路径。
例如:import $ from 'jquery'等价于:
import $ from '/node_modules/jquery/dist/jquery.js'
此时,我们在浏览器中运行index.html,我们看下效果:
我们会发现隔行变色无效,并且控制台报错了。这是因为 import xx from xx 是ES6中导入模块的方式,而 ES6的代码太高级了,浏览器解析不了,所以这一行执行会报错,如果想要浏览器能够解析ES6的代码,我们可以将其通过webpack编译为浏览器可以解析的正常js语法。
3.运行webpack打包
webpack ./src/main.js --output-filename ./bundle.js --mode development
解析:通过 webpack 这么一个前端构建工具, 把 main.js 做了一下处理,生成了一个 bundle.js 的文件。
运行结果如下所示:
PS D:\WorkSpace\vue_book\codes\chapter6\webpack-learn> webpack ./src/main.js --output-filename ./bundle.js --mode development Hash: 57bb64f9c2f92092305b Version: webpack 4.30.0 Time: 381ms Built at: 2019-05-08 20:30:17 Asset Size Chunks Chunk Names ./bundle.js 314 KiB main [emitted] main Entrypoint main = ./bundle.js [./src/main.js] 138 bytes {main} [built] + 1 hidden module
命令格式: webpack 要打包的文件的路径 打包好的输出文件的路径 打包模式(webpack4新增)
4. 修改index.html中的js引用
运行结果如下:
我们发现,在index.html中,我们只需要引入打包后的bundle.js这个文件,如果不采用webpack打包,我们直接在index.html页面中引入文件,至少要引入两个,一个是jquery.js,一个是main.js,而且这两个文件我们可能还要单独去进行代码压缩。
注意:
不推荐直接在index.html里引用任何包和任何CSS文件,而应该在main.js中通过import引用。
每次我们修改了main.js中的代码,都需要重新运行webpack命令进行打包,代码才会生效。因为我们index.html中最终引用的是bundle.js文件。
经过上面的示例,Webpack 可以做什么事情?
1. webpack 能够处理 JS 文件的互相依赖关系。
2. webpack 能够处理JS的兼容问题,把高级的、浏览器不识别的语法,转为低级的,浏览器能正常识别的语法。
6.3 webpack-最基本的配置文件的使用
在前面的示例中,我们发现每次都要运行webpack 要打包的文件的路径 打包好的输出文件的路径 打包模式,这样执行起来非常繁琐。我们可以通过配置文件来让操作变得更加简单。
如果不做任何配置,直接运行命令webpack,会出现如下错误提示:
webpack Insufficient number of arguments or no entry found. Alternatively, run 'webpack(-cli) --help' for usage info.
在项目根目录下创建一个webpack.config.js(默认,可修改)文件来配置webpack。这个配置文件,其实就是一个 JS 文件,通过 Node 中的模块操作,向外暴露了一个配置对象,其代码结构如下:
module.exports = { entry: '', // 入口文件 output: {}, // 出口文件 module: {}, // 处理对应模块 plugins: [], // 对应的插件 devServer: {}, // 开发服务器配置 mode: 'development' // 模式配置 }
由于运行webpack命令的时候,webpack需要指定入口文件和输出文件的路径,所以,我们需要在webpack.config.js
中配置这两个路径。根据项目的代码结构,我们来写一下最基本的webpack配置:
// 导入处理路径的模块 const path = require("path"); // 导出一个配置对象 module.exports = { entry: path.join(__dirname, "./src/main.js"), // 项目入口文件 output: { // 配置输出选项 path: path.join(__dirname, "./dist"), // 配置输出的路径 filename: "bundle.js" // 配置输出的文件名 }, mode: "development" // 模式配置 };
然后再来运行webpack,这次,我们发现运行成功了,运行结果和前面执行:webpack ./src/main.js --output-filename ./bundle.js --mode development 命令是一样的。
思考: 当我们在控制台,直接输入 webpack 命令执行的时候,webpack 做了什么?
1. 首先,webpack 发现我们并没有通过命令的形式,给它指定入口和出口。
2. 于是webpack 就会去项目的根目录中查找一个叫做 “webpack.config.js”的配置文件。
3. 当找到配置文件后,webpack 会去解析执行这个配置文件,当解析执行完配置文件后,就得到了配置文件中,导出的配置对象。
4. 当 webpack 拿到配置对象后,就拿到了配置对象中,指定的入口和出口,然后进行打包构建。
6.4 webpack-dev-server的基本使用
假设我们每次修改了main.js中的代码,我们都需要手动运行webpack打包的命令,然后去刷新浏览器才能看到最新的代码效果,这样操作起来很麻烦,我们希望有那种“热更新”的机制,当修改代码之后,会自动进行打包构建,然后马上能够在浏览器中看到最新的运行效果。
所谓热替换,就是在不刷新网页的情况下,改变代码后,会自动编译并更新页面内容。
我们可以使用 webpack-dev-server 这个工具,来实现自动打包编译的功能。
安装
运行 npm i webpack-dev-server -D 把这个工具安装到项目的本地开发依赖。
安装完成之后,直接在控制台运行:webpack-dev-server,会报错:
webpack-dev-server : 无法将“webpack-dev-server”项识别为 cmdlet、函数、脚本
文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
这是因为我们是在项目中进行本地安装的 webpack-dev-server , 所以无法把它当作 脚本命令,在powershell 终端中直接运行(只有那些安装到全局-g 的工具,才能在终端中正常执行)。此时我们需要借助于package.json
文件中的指令,来进行运行webpack-dev-server
命令。
修改package.json中scripts下面的dev节点,将"webpack --mode development"修改为"webpack-dev-server"。
"scripts": {
"dev": "webpack-dev-server",
注意: webpack-dev-server 这个工具,如果想要正常运行,要求在本地项目中,必须安装 webpack。package.json属于json文件,而json文件中是不能写注释的哦。
webpack4.x将CLI抽离出为单独的包webpack-cli,需要npm install webpack-cli -D单独全局安装不然无法进行编译。
运行命令:npm install webpack webpack-cli webpack-dev-server --save-dev
进行安装。
执行运行:npm run dev,运行结果如下所示:
npm run dev > webpack-learn@1.0.0 dev D:\WorkSpace\vue_book\codes\chapter6\webpack-learn > webpack-dev-server i 「wds」: Project is running at http://localhost:8080/
就可以http://localhost:8080访问了,此时访问webpack-dev-server启动的http://localhost:8080/
网站,发现是一个文件夹的面板,需要点击到src目录下,才能打开我们的index首页,由于此时引用不到bundle.js文件,所以需要修改index.html中script的src属性为/bundle.js。
<script src="/bundle.js">script>
webpack-dev-server 帮我们打包生成的 bundle.js 文件,并没有存放到实际的物理磁盘上;而是直接托管到了电脑的内存中,所以,我们在项目根目录中,根本找不到这个打包好的 bundle.js;。webpack-dev-server 把打包好的文件,以一种虚拟的形式,托管到了咱们项目的根目录中,虽然我们看不到它,但是可以认为, 它和 dist、src 、node_modules 平级,只是看不见,它的文件叫做 bundle.js。
把bundle.js放在内存中的好处是:由于需要实时打包编译,所以放在内存中速度会非常快。
更多内容请移步至:《Vue.js 2.x实践指南》 已出版