本文为 Vue 学习系列笔记第一篇,将持续更新。

文章目录

  • 一、前端工程化
    • 什么是前端工程化
    • 前端工程化的解决方案
  • 二、webpack 的基本使用
    • 什么是 webpack
    • 创建列表隔行变色项目
    • 在项目中安装 webpack
    • 在项目中配置 webpack
    • mode 的可选值
    • webpack.config.js 文件的作用
    • webpack 中的默认约定
    • 自定义打包的入口和出口
  • 三、webpack 中的插件
    • webpack-dev-server 插件
    • 配置 webpack-dev-server
    • html-webpack-plugin 插件
    • 配置 html-webpack-plugin
    • devServer 节点
  • 四、webpack 中的 loader
    • loader 概述
    • loader 的调用过程
    • 打包处理 css 文件
    • 打包处理 less 文件
    • 打包处理样式表中与 url 路径相关的文件
    • 打包处理 js 文件中的高级语法
  • 五、打包发布
    • 为什么要打包发布?
    • 配置 webpack 的打包发布
    • 把 JS 文件统一生成到 js 目录中
    • 把图片文件统一生成到 image 目录中
    • 自动清理 dist 目录下的旧文件
  • 六、Source Map
    • 生产环境遇到的问题
    • 什么是 Source Map
    • webpack 开发环境下的 Source Map
    • 解决默认 Source Map 问题
    • webpack 生产环境下的 Source Map
    • 只定位行数,不暴露源码
    • Soure Map 最佳实践
  • 七、拓展
    • webpack 中 @ 的原理与好处

一、前端工程化


什么是前端工程化

前端工程化指的是:在企业级的前端项目开发中,把前端开发所需的工具、技术、流程、经验等规范化、标准化。

企业中 Vue 项目 和 React 项目,都是基于工程化的方式进行开发的。这使得前端开发自成体系,有一套标准的开发方案和流程。

而为了让前端开发能够 “ 自成体系 ”,需要从下面四个方面进行考虑:

  • 模块化: js 的模块化、css 的模块化、资源的模块化
  • 组件化:复用现有的 UI 结构、样式、行为
  • 规范化:目录结构的划分、编码规范化、接口规范化、文档规范化、Git 分支管理
  • 自动化:自动化构建、自动部署、自动化测试

更多介绍可参考此文:前端工程化的理解

前端工程化的解决方案

早期的前端工程化解决方案(目前已被边缘化):

  • grunt
  • gulp

目前主流的工程化解决方案:

  • webpack
  • parcel

本篇文章主要介绍 webpack 如何解决前端工程化问题。

二、webpack 的基本使用


什么是 webpack

Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。

它提供了友好的前端模块化开发支持,以及 代码压缩混淆、处理浏览器 JavaScript 的兼容性、性能优化 等强大的功能。有效地提高了开发效率和项目的可维护性。

创建列表隔行变色项目

具体步骤如下:

  1. 新建项目空白目录,并运行 npm init –y 命令,初始化包管理配置文件 package.json
  2. 新建 src 源代码目录
  3. 新建 src -> index.html 首页和 src -> index.js 脚本文件
  4. 初始化首页基本的结构
  5. 运行 npm install jquery –S 命令,安装 jQuery
  6. 通过 ES6 模块化的方式导入 jQuery,实现列表隔行变色效果

利用 jQuery,很轻松我们就可以实现代码书写,如下:

但是打开 index.html 页面时,你会发现一个问题:它报错了!

出现了兼容性问题,那么怎么解决呢?这就要用到 webpack。下面我们先来安装 webpack,再讲解如何解决此问题。

在项目中安装 webpack

在终端运行如下命令,安装 webpack 相关的两个包:

npm install --save-dev webpack

说一下 package.json 中 dependencies 和 devDependencies 的区别

  • dependencies:应用能够正常运行所依赖的包。无论是开发、还是上线发布都要用到的 npm 包放在这里。
    用法:--save,可简写为 -S
  • devDependencies: 开发应用时所依赖的工具包。仅在开发时会用到的 npm 包放在这里。
    用法:--save-dev,可简写为 -D

在项目中配置 webpack

① 在项目根目录中,创建名为 webpack.config.js 的 webpack 配置文件,并初始化如下的基本配置:

 module.exports = {mode: 'development'}

注意:mode 用来指定构建模式。可选值有 development(开发阶段) 和 production(上线阶段)。

② 在 package.json 的 scripts 节点下,新增 dev 脚本(最好命名为 dev,当然你也可以指定其他名称)

 "scripts": {"dev":"webpack"}

注意:script 节点下的脚本,可以通过 npm run 执行,如 npm run dev

③ 在终端中运行 npm run dev 命令,启动 webpack 进行项目的打包构建。

④ webpack 打包构建完成后,会自动生成 dist 文件夹,里面含有文件 main.js。在 index.html 中导入此模块文件 main.js,即可解决之前导入模块文件遇到的兼容性问题等。

再说一下 main.js 文件,它相当于将此前有兼容性问题的模块文件 index.js 和 jquery.js 进行了合并,通过此前 webpack 打包后的终端显示的结果也可看出这一点。

mode 的可选值

  • development

    1. 开发环境
    2. 不会对打包生成的文件进行代码压缩和性能优化
    3. 打包速度快,适合在开发阶段使用
  • production
    1. 生产环境
    2. 会对打包生成的文件进行代码压缩和性能优化
    3. 打包速度很慢,仅适合在项目发布阶段使用

webpack.config.js 文件的作用

webpack.config.js 是 webpack 的配置文件。webpack 在真正开始打包构建之前,会先读取这个配置文件,从而基于给定的配置(mode),对项目进行打包。

注意:由于 webpack 是基于 node.js 开发出来的打包工具,因此在它的配置文件中,支持使用 node.js 相关的语法和模块进行 webpack 的个性化配置。

webpack 中的默认约定

上面一系列的操作看似没有什么破绽,可是你有没有想到一个问题,那就是 webpack 怎么知道要去打包 src / index.js 文件呢?

这是因为在 webpack 中有如下的默认约定:

  1. 默认的打包入口文件为 src / index.js
  2. 默认的输出文件路径为 dist / main.js

注意:可以在 webpack.config.js 中修改打包的默认约定。

自定义打包的入口和出口

在 webpack.config.js 配置文件中,通过 entry 节点指定打包的入口。通过 output 节点指定打包的出口。

例如,我们打算将 ./src/index1.js 文件进行打包,输出到 dist 文件夹中,名称为 bundle.js 。如下:

 module.exports = {mode: 'development',entry: './src/index1.js',   // 打包文件入口的路径output: {path: path.join(__dirname, 'dist'),           // 输出文件存放路径filename: 'bundle.js'                           // 输出文件的名称}}

npm run dev 重新打包后,显示:

三、webpack 中的插件


webpack-dev-server 插件

接下来我们又面临一个问题,难道说每次修改完源代码,都要重新打包文件吗?这也太麻烦了吧。幸运的是,这里可以安装一个插件 webpack-dev-server 来解决这个问题,使得打包文件会自动更新。

它类似于 node.js 中的 nodemon 工具。每当修改了源代码,webpack 会自动进行项目的打包和构建。

安装命令如下:

 npm install webpack-dev-server --save-dev

配置 webpack-dev-server

① 修改 package.json 文件中的 "scripts"

  "scripts": {"dev": "webpack serve"}

② 再次运行 npm run dev 命令,重新进行项目的打包

通过终端输出结果可以看到:webpack output is served from /,意思是说 output 文件被生成在了文件根目录下面,但是我们并没有在根目录下面发现指定的 output 文件 bundle.js。

这是因为,webpack-dev-server 插件将新生成的 bundle.js 放在了内存中,而非物理磁盘中,因此我们看不到。放在内存中的好处有两个:速度快、防止频繁读写硬盘导致寿命损耗。

同时,在 html 文件中引入时,我们也要引入最新的 bundle.jsj 文件。需要进行如下修改:

    <!-- <script src="../dist/bundle.js"></script> --><script src="/bundle.js"></script>

③ 在浏览器中访问 http://localhost:8080 地址,查看自动打包结果

这样,在修改完源代码后,无需重启服务器,也无需手动刷新页面,就可以得到最新的页面效果。

html-webpack-plugin 插件

又有一个问题,每次访问 index.html 页面,需要打开 http://localhost:8080 后再点击 src 文件夹才能访问,太过复杂。

这里可以利用 html-webpack-plugin 插件,它可以将 src 文件夹中的 index.html 复制一份放在根目录 / 下面。这样以后只要打开 http://localhost:8080 页面,即可访问到 index.html 。

安装命令如下:

 npm i --save-dev html-webpack-plugin

配置 html-webpack-plugin

在 webpack.config.js 文件中,进行如下配置操作:

 // 1. 导入 html-webpack-plugin 这个插件,得到插件的构造函数const HtmlPlugin = require('html-webpack-plugin');// 2. new 构造函数,创建插件的实例对象const htmlPlugin = new HtmlPlugin({template: './src/index.html',       // 指定要复制的文件filename: './index.html'           // 指定复制文件的名称和目的路径});module.exports = {mode: 'development',// 3. 插件的数组,将来 webpack 在运行时,会加载并调用这些插件plugins: [htmlPlugin]}

这样,打开 html://localhost:8080 就会加载出 index.html 显示的页面:

注意:这里 html-webpack-plugin 插件的使用还需强调两点:

  1. 通过插件复制到项目根目录中的 index.html 页面,也被放到了内存中。
  2. 插件在生成的 index.html 页面中,自动注入了打包的 bundle.js 文件:

    因此,在 index.html 中我们可以省去对 bundle.js 的手动引用。

devServer 节点

在 webpack.config.js 配置文件中,可以通过 devServer 节点对 webpack-dev-server 插件进行更多的配置。

比如,你懒得每次还需要手动打开 html://localhost:8080 页面,想让它配置之后自动打开浏览器显示该页面,你就可以这样配置:

    devServer: {open: true,         // 首次打包成功后,自动打开浏览器port: 80,           // 指定端口。在 http 协议中,端口号 80,可以被省略host: '127.0.0.1'   // 指定运行的主机地址}

四、webpack 中的 loader


loader 概述

在实际开发过程中,webpack 默认只能打包处理以 .js 为后缀名的模块。其他非 .js 后缀名结尾的模块,webpack 默认处理不了,需要调用 loader 加载器才能正常打包,否则会出现报错。

loader 加载器的作用:协助 webpack 打包处理特定的文件模块。如下:

  1. css-loader:可以打包 .css 相关的文件
  2. less-loader:可以打包处理 .less 相关的文件
  3. babel-loader:可以打包处理 webpack 无法处理的高级 JS 语法

loader 的调用过程

打包处理 css 文件

在 webpack 中,一切皆模块,都可以通过 ES6 导入语法进行导入和使用。例如,我们要引入 index.css 文件,可以在 webpack 入口文件 index.js 中进行如下操作:

但是你立刻会发现,它报错了!

因为 webpack 只能处理 .js 文件,这里需要利用第三方的 loader 加载器。

怎么配置对应 loader 呢 ?

① 运行 npm i style-loader css-loader -D 进行安装处理 css 文件的 loader

② 在 webpack.config.js 中做出如下配置:

    module: {rules: [// 处理 .css 文件的 loader{ test: /\.css$/, use: ['style-loader', 'css-loader'] },]}

其中,test 表示匹配的文件类型, use 表示对应要调用的 loader 。

注意:use 数组中指定的 loader 顺序是固定的。这是因为当多个 loader 的调用时,其调用顺序是:从后往前调用 。

打包处理 less 文件

① 运行 npm i less-loader less -D 安装处理 less 文件的 loader

② 在 webpack.config.js 中做出如下配置:

    module: {rules: [// 处理 .less 文件的 loader{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },]}

打包处理样式表中与 url 路径相关的文件

在此之前先说一下 base64 格式的图片(base64在线转换工具)

通过下面两种方式显示出的图片是一样的:

它们的区别在于:使用前者时,浏览器在加载完 HTML 标签后,还需要发送额外请求才能得到该图片并进行渲染。而第二种方式,浏览器不用再请求服务器调用图片资源,在请求标签时就将该图片请求下来,减少了服务器访问次数。
但是它有个小缺点,会增加 css 的体积或者存储在数据库中增大了数据库服务器的压力。不适用于大图片的转换。

这里我们有个需求,打算设置 index.html 文件中 <img> 标签的属性:

这里 webpack 又遇到难题了,无法引入 .png 文件,这里又需要借助 loader 加载器:

怎么配置对应 loader 呢 ?

① 运行 npm i url-loader file-loader -D 命令安装对应处理 url 的 loader

② 在 webpack.config.js 中做出如下配置:

    module: {rules: [// 处理图片类型文件{ test: /\.jpg|png|gif$/, use: 'url-loader?limit=22229' }]}

其中 ? 之后的是 loader 的参数项:

  1. limit 用来指定图片的大小,单位是字节(byte)
  2. 只有 ≤ limit 大小的图片,才会被转为 base64 格式的图片

可以看到引入的 logo.png 图片就被转换为了 base64 格式:

打包处理 js 文件中的高级语法

webpack 只能打包处理一部分高级的 JavaScript 语法。而对于一些 webpack 无法处理的语法,需要借助于 bable-loader 进行打包处理。

例如 webpack 无法处理下面的 js 代码:

怎么配置 babel-loader 呢?

① 执行下面代码进行安装

 npm i babel-loader @babel/core @babel/plugin-proposal-decorators -D

② 在 webpack.config.js 中做出如下配置:

    module: {rules: [// 使用 babel-loader 处理高级 JS 语法// 注意:必须使用 exclude 排除项。因为 node_modules 目录下的第三方包不需要打包{ test: /\.js$/, use: 'babel-loader', exclude: /node_module/ },]}

③ 在项目根目录下,创建名为 babel.config.js 的配置文件,定义 Babel 的配置项 如下:

 module.exports = {// 声明 babel 可以的插件// webpack 在调用 babel-loader 的时候,会先加载 plugins 插件来使用plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]]}

五、打包发布


为什么要打包发布?

项目开发完成之后,使用 webpack 对项目进行打包发布的主要原因有以下两点:

  • 开发环境下,打包生成的文件存放于 内存 中,无法获取到最终打包生成的文件
  • 开发环境下,打包生成的文件不会进行代码压缩和性能优化

为了让项目能够在生产环境中高性能的运行,因此需要对项目进行打包发布。

配置 webpack 的打包发布

在 package.json 文件的 script 节点下,新增 bulid 命令:

  "scripts": {"dev": "webpack serve","build": "webpack --mode production"    }

项目发布时,执行 build 命令: npm run build 。生成 dist 文件,压缩此文件发给后端人员就 OK 了。

注意:

  1. --model 是一个参数项,用来指定 webpack 的运行模式。
  2. production 代表生产环境,进行代码压缩和性能优化。
  3. 通过 --model 指定的参数项,会 覆盖 webpack.config.js 中的 model 选项。

把 JS 文件统一生成到 js 目录中

直接将各种杂乱的文件打包肯定是不行的,这里我们来进行优化一下,将 Javascript 文件统一生成到 js 目录中。具体操作:

在 webpack.config.js 配置文件的 output 节点中,进行如下配置:

把图片文件统一生成到 image 目录中

在 webpack.config.js 配置文件的 module => rules 节点中,进行如下配置:

 // 处理图片类型文件,多个参数可用 & 分隔{ test: /\.jpg|png|gif$/, use: 'url-loader?limit=229&outputPath=images' }

最终实现:

自动清理 dist 目录下的旧文件

为了每次打包发布时能够 自动清理掉 dist 目录中的文件夹,可以安装配置 clean-webpack-plugin 插件

 npm i clean-webpack-plugin -D

接下来如何配置呢 ?

在 webpack.config.js 配置文件中先引入:

 // 解构赋值const { CleanWebpackPlugin } = require('clean-webpack-plugin');

然后,在 plugins 节点(数组)中添加:

 new CleanWebpackPlugin()

可参考对应的 npm 官方文档查看具体描述 => clean-webpack-plugin

六、Source Map


生产环境遇到的问题

前端项目在投入生产环境之前,都需要对 JavaScript 源代码进行压缩混淆,从而减小文件的体积,提高文件的加载效率。

此时就不可避免的产生了另一个问题:对压缩混淆之后的代码 除错(debug)是一件极其困难的事情。

因为,通常 JavaScript 的解释器会告诉你,第几行第几列代码出错。但是,这对于转换后的代码毫无用处。

而要成功解决这个问题就要用到这里所要介绍的 Source Map 。

什么是 Source Map

Source Map 就是一个信息文件,里面储存着位置信息。也就是说,Source Map 文件中存储着代码压缩混淆前后的对应关系。

有了它,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码,能够极大的方便后期的调试。

webpack 开发环境下的 Source Map

在开发环境下,webpack 默认启用了 Source Map 功能。当程序运行出错时,可以直接在控制台提示错误行的位置,并定位到具体的源代码。

但是,开发环境下默认生成的 Source Map 记录的是 生成后的代码的位置。会导致运行时报错的行数与源代码的行数不一致的问题。

解决默认 Source Map 问题

开发环境下,推荐在 webpack.config.js 中添加如下的配置,即可 保证运行时报错的行数与源代码的行数保持一致:

module.exports = {// 在开发调试阶段,建议将 devtool 做如下设置devtool: 'eval-source-map',...
}

这样就可以精准定位到源代码了,方便调试工作。

webpack 生产环境下的 Source Map

在生产环境下,最好省略 devtool 选项,使得最终生成的文件中不包含 Source Map。这能够防止原始代码通过 Source Map 的形式暴露给别有所图之人,提高安全性。

只定位行数,不暴露源码

为了兼顾安全性同时又想定位具体行号,也可以有个折中方案。

在生产环境下,如果 只想定位报错的具体行数,且不想暴露源码。可以在 webpack.config.js 中这样配置:

module.exports = {// 定位源码行号,但不暴露源码devtool: 'nosources-source-map',...
}

Soure Map 最佳实践

开发环境下:

  1. 建议把 devtool 的值设置为 eval-source-map
  2. 好处:可以精准定位到具体的错误行

生产环境下:

  1. 建议 关闭 Source Map 或将 devtool 的值设置为 nosources-source-map
  2. 好处:防止源码泄露,提高网站的安全性

七、拓展


webpack 中 @ 的原理与好处

在引入文件时如果这个文件藏得很深,你不得不去这样引入:

 import msg from '../../msg'

那么多的 ../ 是不是看上去都有些眼花缭乱 ?而如果利用 @,你就可以解决这个烦恼,如下:

 import msg from '@/msg'

但是,使用 @ 时需要在 webpack.config.js 中进行配置:

module.exports = {...resolve: {alias: {// @ 表示 src 这一层目录'@': path.join(__dirname, './src/')}}
}

写在最后

其实在实际开发中根本不需要自己去配置 webpack。实际开发中会使命令行工具( CLI )一键生成带有 webpack 的项目,也就是开箱即用,所有配置都是现成的。但是,如果你能搞清其中原理当然是有百利而无一害的。

Vue「一」—— webpack 的基本使用及常用配置相关推荐

  1. Vue「六」前端路由、vue-router

    Vue 系列笔记第六篇.本文参考:>> 黑马程序员 Vue 全套视频教程 系列文章阅读

  2. Vue「五」—— 动态组件、插槽、自定义指令

    Vue 系列笔记第五篇.本文参考:>> 黑马程序员 Vue 全套视频教程 系列文章阅读

  3. Vue「四」—— 组件生命周期、数据共享

    Vue 系列笔记第四篇.本文参考:>> 黑马程序员 Vue 全套视频教程 Vue 系列文章

  4. Vue「三」—— vue 侦听器、vue 计算属性、vue-cli、vue 组件

    本文为 Vue 系列笔记第三篇.参考:>> 黑马程序员 Vue 全套视频教程 系列文章阅读

  5. Vue「二」—— vue 基本使用 、vue 指令 、vue 过滤器

    Vue 系列笔记第二篇,欢迎阅读.文章参考:>> 黑马程序员 Vue 全套视频教程 系列文章阅读

  6. 「AutoML」激活函数如何进行自动学习和配置

    2019-10-26 12:48:04 大家好,欢迎来到专栏<AutoML>,在这个专栏中我们会讲述AutoML技术在深度学习中的应用.这一期讲述在激活函数设计中的应用. 作者&编 ...

  7. ospf多区域配置为什么ping不通_「实战」动态路由多区域 OSPF 基本配置,一分钟了解下...

    1.实战目的 (1)在路由器上启动 OSPF 路由进程 (2)启用参与路由协议的接口,并且通告网络及所在的区域 (3)LSA 的类型和特征 (4)不同路由器类型的功能 (5)OSPF 拓扑结构数据库的 ...

  8. _CentOS「linux」学习笔记11:crontab定时任务常用参数和基本语法

    ​linux基础操作:主要介绍了crontab定时任务的常用参数和基本语法 crontab[定时任务,重复执行特定的命令或脚本,类似Windows下的计划任务] crontab常用参数和基本语法介绍: ...

  9. .net vue漂亮登录界面_基于 electron-vue 开发的音乐播放器「实践」

    作者:XiaoTuGou 转发链接:https://github.com/SmallRuralDog 前言 基于 electron-vue 开发的音乐播放器,界面模仿QQ音乐. 技术栈electron ...

最新文章

  1. 简单五子棋问题,java实现
  2. beanstalkd消息队列在生产环境的应用
  3. oracle截取字符串
  4. 北邮国院c语言期末考试题,北邮C语言复习题2014.ppt
  5. 让Web开发者事半功倍的8个网站
  6. 实验六 数组 (2)
  7. php 上传大文件主要涉及配置upload_max_filesize和post_max_size两个选项(转)
  8. zookeeper的设计猜想-防止单点故障
  9. MySQL分页查询语句
  10. Idea的一些调试技巧及设置todo
  11. 【C++ STL学习之六】STL算法之for_each
  12. python统计行号_用Python实现两个文件的不同行的编号
  13. “docker run”VS“docker exec”,这两个命令有区别吗?
  14. 基于Python的心电图上位机诊断软件
  15. 3U VPX高性能数据处理板(XC7K325T FMC载板)
  16. 角度值计算机符号,数学角度符号_请问各种数学符号的读音比如αβγδελζηθξσφψω等等的读音_淘题吧...
  17. 瞅瞅Levels.fyi发布的2020年度程序员收入报告
  18. C语言求卢卡斯序列,卢卡斯数列 斐波那契数列和卢卡斯数列!
  19. android高仿微信表情输入与键盘输入详解
  20. 解决电脑蓝牙可以连接手机电脑等设备却无法连接到耳机的问题

热门文章

  1. docker mysql 日志_在docker mysql容器中启用日志记录
  2. 聊天机器人-AIML人工智能标记语言
  3. WAMPServer使用
  4. java 中间容器 表格_【JAVA SE基础篇】45.迭代器、Collections工具类以及使用容器存储表格...
  5. stm32单片机屏幕一直闪_用STM32做一个微型掌上示波器项目——终于鼓起在大牛前献丑的无比勇气...
  6. Java基础---学Java怎么能不了解多线程---Lambda表达式
  7. 两个div在同一行且不换行
  8. tar [-zxcvfpP]语法
  9. UWP 手绘视频创作工具技术分享系列 - 位图的绘制
  10. 求数组三项之和最接近某个目标数字