前端工程化(ES6模块化和webpack打包)
模块化的相关规范
模块化的分类
浏览器端的模块化
- AMD(Asynchronous Module Definition,异步模块定义),代表产品为:Require.js
- CMD(Common Module Definition,通用模块定义),代表产品为:Sea.js
服务器端的模块化
服务器端的模块化规范是使用CommonJS规范:
- 使用require引入其他模块或者包
- 使用exports或者module.exports导出模块成员
- 一个文件就是一个模块,都拥有独立的作用域
ES6模块化
大一统的模块化规范。 ES6模块化规范中定义:
- 每一个js文件都是独立的模块
- 导入模块成员使用import关键字
- 暴露模块成员使用export关键字
在NodeJS中通过babel体验ES6模块化
安装babel及使用
在项目文件夹打开终端,输入命令安装插件:
npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/node
安装完毕之后,再次输入命令安装:
npm install --save @babel/polyfill
在项目根目录中创建
babel.config.js
文件进入该文件,写入以下代码:
1
2
3
4
5
6
7
8
9
10
11
12const presets = [
["@babel/env", {
targets: {
edge: "17",
firefox: "60",
chrome: "67",
safari: "11.1"
}
}]
]
//暴露(到导出)
module.exports = { presets }在根目录新建一个
index.js
文件后,输入命令npx babel-node ./index.js
即可运行。
设置默认导入导出
- 默认导出
1 | // m1.js文件 |
- 默认导入
1 | import m1 from './m1.js' |
注意:在一个模块中,只允许使用export default向外默认暴露一次成员,千万不要写多个export default。
设置按需导入/导出
- 按需导出
1 | export let s1 = '111'; |
- 按需导入
1 | import { s1, s2 } from './m1.js' |
直接导入并执行代码
1 | import "./test2.js" |
webpack
webpack是一个流行的前端项目构建工具,可以解决目前web开发的困境。webpack提供了模块化支持,代码压缩混淆,解决js兼容问题,性能优化等特性,提高了开发效率和项目的可维护性。
webpack基本使用
新建项目空白目录,并在根目录终端运行如下命令,初始化包管理配置文件
package.json
1
npm init -y
新建 src 源代码目录,并且在 src 下面新建 index.html 首页,然后初始化 首页基本的结构,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- 传统模式是如下引入,但是我们要用模块化思维 -->
<!-- <script src="./index.js"></script> -->
</head>
<body>
<ul>
<li>这是第 1 个li</li>
<li>这是第 2 个li</li>
<li>这是第 3 个li</li>
<li>这是第 4 个li</li>
<li>这是第 5 个li</li>
<li>这是第 6 个li</li>
<li>这是第 7 个li</li>
<li>这是第 8 个li</li>
<li>这是第 9 个li</li>
</ul>
</body>
</html>在终端执行如下命令,安装
jQuery
1
npm install jquery -s
继续在 src 下面创建 index.js,并写入代码
1
2
3
4
5
6// 用 import 导入 jquery
import $ from 'jquery'
$(function() {
$('li:odd').css('background', 'blue')
$('li:even').css('background', 'lightblue')
})要安装最新版本或特定版本,请运行以下命令之一
1
2
3npm install --save-dev webpack
# 或指定版本
npm install --save-dev webpack@<version>如果你使用 webpack v4+ 版本,并且想要在命令行中调用
webpack
,你还需要安装 CLI。1
npm install --save-dev webpack-cli
在项目的根目录中,创建
webpack.config.js
文件进行如下配置1
2
3module.exports = {
mode: 'development' //mode用来指定构建模块
}注意:development(用于开发时期)不会压缩文件,改为prodection(用于发布时期)会压缩文件。
在 package.json 配置文件中的
package.json
的scripts 节点下,新增 dev、build 脚本1
2
3
4
5"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --config webpack.config.js",
"dev": "webpack"
},在终端中运行如下命令,启动 webpack 进行项目打包
1
npm run dev
打包完成之后,会自动创建一个 dist 文件夹,里面包含 一个 main.js ,此时再回到 src -> index.html 中,重新引入打包之后的 js文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- 传统模式是如下引入,但是我们要用模块化思维 -->
<script src="../dist/main.js"></script>
</head>
<body>
<ul>
<li>这是第 1 个li</li>
<li>这是第 2 个li</li>
<li>这是第 3 个li</li>
<li>这是第 4 个li</li>
<li>这是第 5 个li</li>
<li>这是第 6 个li</li>
<li>这是第 7 个li</li>
<li>这是第 8 个li</li>
<li>这是第 9 个li</li>
</ul>
</body>
</html>这时可正常运行该文件
配置入口出口文件
- 在webpack 4.x中,默认会将src/index.js 作为默认的打包入口js文件
- 默认会将dist/main.js 作为默认的打包输出js文件
如果不想使用默认的入口/出口js文件,我们可以通过改变 webpack.config.js 来设置入口/出口的js文件,如下
1 | const path = require("path"); |
设置webpack自动打包
默认情况下,我们更改入口js文件的代码,需要重新运行命令打包webpack,才能生成出口的js文件。那么每次都要重新执行命令打包,这是一个非常繁琐的事情,那么,自动打包可以解决这样繁琐的操作。
安装自动打包功能的包:webpack-dev-server:
npm install webpack-dev-server -D
修改package.json中的dev指令
1
2
3"scripts":{
"dev":"webpack-dev-server"
}将引入的js文件路径更改为:
<script src="/main.js"></script>
(main为默认输出文件)运行npm run dev,进行打包
打开网址查看效果:http://localhost:8080
webpack-dev-server
自动打包的输出文件,默认放到了服务器的根目录中.
若npm run dev出错,则查看版本是否不兼容,安装低版本。本次处理方式:降低webpack-cli版本:npm i webpack-cli@3.3.12 -D
配置html-webpack-plugin
因为当我们访问默认的 http://localhost:8080/的时候,看到的是一些文件和文件夹,想要查看我们的页面,还需要点击文件夹点击文件才能查看,那么我们希望默认就能看到一个页面,而不是看到文件夹或者目录。使用html-webpack-plugin 可以生成一个预览页面。
安装默认预览功能的包html-webpack-plugin:
npm install html-webpack-plugin -D
修改webpack.config.js文件,添加如下内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14//导入包
const HtmlWebpackPlugin = require("html-webpack-plugin");
//创建对象
const htmlPlugin = new HtmlWebpackPlugin({
//设置生成预览页面的模板文件
template: "./src/index.html",
//设置生成的预览页面名称
filename: "index.html"
});
module.exports = {
mode: 'development', //mode用来指定构建模块
plugins: [htmlPlugin] //plugins数组存放用到的插件
}在自动打包完毕之后,默认打开服务器网页,实现方式就是打开package.json文件,修改dev命令
1
"dev": "webpack-dev-server --open --host 127.0.0.1 --port 9999"
webpack中的加载器
1 | 通过loader打包非js模块:默认情况下,webpack只能打包js文件,如果想要打包非js文件,需要调用loader加载器才能打包。 |
- less-loader
- url-loader:打包处理css中与url路径有关的文件
- babel-loader:处理高级js语法的加载器
打包处理CSS文件
运行
npm i style-loader css-loader -D
命令,安装处理 css 文件的 loader在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下:
1
2
3
4
5
6
7
8// 所有第三方文件模块的匹配规则
module: {
rules: [ {
test: /\.css$/, use: ['style-loader', 'css-loader']
} ] }
// test 表示匹配的文件类型, use 表示对应要调用的 loader
// use 数组中指定的 loader 顺序是固定的
// 多个 loader 的调用顺序是:从后往前调用
打包处理 less文件
运行
npm i less-loader less -D
命令在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下
1
2
3
4
5
6
7
8
9
10
11module.exports = {
mode: 'development', //mode用来指定构建模块
plugins: [htmlPlugin],
module: {
rules: [
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
// 添加下面这一行
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }
]
}
}
打包处理 scss文件
运行 npm i sass-loader node-sass -D 命令
在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下:
1
2
3
4module: {
rules: [
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }
] }
安装post-css自动添加css的兼容性前缀
安装包
npm install postcss-loader autoprefixer -D
在项目根目录创建并配置postcss.config.js文件
1
2
3
4const autoprefixer = require("autoprefixer");
module.exports = {
plugins:[ autoprefixer ]
}配置规则:更改webpack.config.js的module中的rules数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14module.exports = {
......
plugins:[ htmlPlugin ],
module : {
rules:[
{
//test设置需要匹配的文件类型,支持正则
test:/\.css$/,
//use表示该文件类型需要调用的loader
use:['style-loader','css-loader','postcss-loader']
}
]
}
}
打包样式表中的图片以及字体文件
在样式表css中有时候会设置背景图片和设置字体文件,一样需要loader进行处理。使用url-loader和file-loader来处理打包图片文件以及字体文件。
安装包
npm install url-loader file-loader -D
配置规则:更改webpack.config.js的module中的rules数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14module.exports = {
......
plugins:[ htmlPlugin ],
module : {
rules:[
{
test:/\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/,
//limit用来设置字节数,只有小于limit值的图片,才会转换
//为base64图片
use:"url-loader?limit=16940"
}
]
}
}
打包js文件中的高级语法
安装babel转换器
npm install babel-loader @babel/core @babel/runtime -D
安装babel语法插件包
npm install @babel/preset-env @babel/plugin-transform-runtime @babel/plugin-proposal-class-properties -D
在项目根目录创建并配置babel.config.js文件
1
2
3
4module.exports = {
presets:["@babel/preset-env"],
plugins:[ "@babel/plugin-transform-runtime", "@babel/plugin-proposal-class-properties" ]
}配置规则:更改webpack.config.js的module中的rules数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14module.exports = {
......
plugins:[ htmlPlugin ],
module : {
rules:[
{
test:/\.js$/,
use:"babel-loader",
//exclude为排除项,意思是不要处理node_modules中的js文件
exclude:/node_modules/
}
]
}
}
Vue单文件组件
传统Vue组件的缺陷:
全局定义的组件不能重名,字符串模板缺乏语法高亮,不支持css(当html和js组件化时,css没有参与其中)
没有构建步骤限制,只能使用H5和ES5,不能使用预处理器(babel)
解决方案:
使用Vue单文件组件,每个单文件组件的后缀名都是.vue,每一个Vue单文件组件都由三部分组成:
- template组件组成的模板区域
- script组成的业务逻辑区域
- style样式区域
1 | <template> |
配置.vue文件的加载器
安装vue组件的加载器
npm install vue-loader vue-template-compiler -D
(若出错,可降低版本加载器)更改webpack.config.js的module中的rules数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 导入包
const VueLoaderPlugin = require("vue-loader/lib/plugin");
module.exports = {
mode: 'development', //mode用来指定构建模块
// 用其构造函数创建一个VueLoaderPlugin实例
plugins: [htmlPlugin, new VueLoaderPlugin()],
module: {
rules: [
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
// 引入
{ test: /\.vue$/, use: "vue-loader" }
]
}
}
在 webpack 项目中使用 vue
- 运行
npm i vue –S
安装 vue - 在 src -> index.js 入口文件中,通过
import Vue from 'vue'
来导入 vue 构造函数 - 创建 vue 的实例对象,并指定要控制的 el 区域
- 通过 render 函数渲染 App 根组件
1 | // 1. 导入 Vue 构造函数 |
webpack打包发布
在项目上线之前,我们需要将整个项目打包并发布。
配置package.json
1
2
3
4
5
6
7
8// 在package.json文件中配置 webpack 打包命令
// 该命令默认加载项目根目录中的 webpack.config.js 配置文件
"scripts": {
// 用于打包的命令
"build": "webpack -p",
// 用于开发调试的命令
"dev": "webpack-dev-server --open --host 127.0.0.1 --port 3000",
}在项目打包之前,可以将dist目录删除,生成全新的dist目录
Vue脚手架
Vue 脚手架用于快速生成 Vue 项目基础架构,其官网地址为:https://cli.vuejs.org/zh/
基本使用
安装最新版本的 Vue 脚手架
1
npm install -g @vue/cli
基于脚手架创建vue项目
1
2
3
4
5
6
7
8
9// 1. 基于 交互式命令行 的方式,创建 新版 vue 项目
vue create my-project
// 2. 基于 图形化界面 的方式,创建 新版 vue 项目
vue ui
// 3. 基于 2.x 的旧模板,创建 旧版 vue 项目
npm install -g @vue/cli-init
vue init webpack my-project
方法一
- 执行
vue create my-project
,出现选项,有2.0/3.0的默认构建方式和自定义方式;
- 这里我们选择自定义模式,在需要的选项按下空格即可选中,选完后按下回车进行确认;
- 接着选择你的版本(2.x/3.x),接着会让你选择是否使用历史模式,我们这里选择n,表示使用哈希模式;
- 接着是选择ESLint模式,这里选择
Standard config
- 然后让选择什么时候进行ESLint校验,默认选择
Lint on save
就好 - 接着会询问那些工具的创建文件保存在单个文件还是一个总文件,这里选择默认的
In dedicated config files
- 最后会询问你是否将你的选择做成一个模版供后续使用,可以选择
n
运行
- 进入项目目录,执行
npm run server
即可运行项目
- 根据提示,复制
http://localhost:8080/
到浏览器中即可
方法二
在需要创建项目的目录下,打开命令行输入
1
vue ui
输入命令后会自动打开浏览器到可视化界面
- 点击创建新项目
预设,可以选择默认或自己的模版,这里以手动配置来学习(一定要选babel和Router以及Lint相关、使用配置文件开关)
接着配置页面,默认的选项不用管,只需选择ESLint的
Standard config
模式
- 接着保存,你可以将其保存为一个模版,也可以不保存。然后确认即可开始创建项目;
- 创建完成后会出现如下面板,点击如下运行,可运行并管理项目。点击启动app可本地查看项目效果。
项目结构分析
Vue脚手架产生的项目结构如下:
node_modules
为依赖包目录public
为静态资源目录src
为组件源码目录babel.config.js
为babel的配置文件
Vue 脚手架的自定义配置
通过 package.json 配置项目
注意:不推荐使用这种配置方式。因为 package.json 主要用来管理包的配置信息;为了方便维护,推荐将 vue 脚手架相关的配置,单独定义到 vue.config.js 配置文件中。
1 | // 必须是符合规范的json语法 |
通过单独的配置文件配置项目
在项目的根目录创建文件
vue.config.js
在该文件中进行相关配置,从而覆盖默认配置
1
2
3
4
5
6// vue.config.js
module.exports = {
devServer: {
port: 8888
}
}
Element-UI
Element-UI:一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库。
官网地址: http://element-cn.eleme.io/#/zh-CN
基于命令行方式手动安装
安装依赖包
1
npm i element-ui -S
在
src/main.js
文件中添加三行代码引入1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18import Vue from 'vue'
import App from './App.vue'
import router from './router'
// 以下三行新增代码为手动安装ElementUI
// 导入组件库
import ElementUI from 'element-ui'
// 导入组件相关样式
import 'element-ui/lib/theme-chalk/index.css'
// 配置Vue插件
Vue.use(ElementUI);
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')使用组件代码,将如下代码复制到src/App.vue文件中
.assets/Snipaste_2021-08-17_21-40-49.jpg)
.assets/Snipaste_2021-08-17_21-44-04.jpg)
接着保存并运行项目
1
npm run serve
.assets/Snipaste_2021-08-17_21-49-49.jpg)
基于图形化界面自动安装
运行
vue ui
命令,打开图形化界面通过 Vue 项目管理器,进入具体的项目配置面板,方便演示这里新建一个项目,方法见上文。然后运行项目并启动app。
点击
插件 -> 添加插件
,进入插件查询面板
搜索
vue-cli-plugin-element
安装配置插件,实现按需导入,从而减少打包后项目的体积
.assets/Snipaste_2021-08-17_22-01-31.jpg)
- 接着将按钮代码同样复制到目标文件中即可。