模块化的相关规范

模块化的分类

浏览器端的模块化

  • 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
    12
    const presets = [
    ["@babel/env", {
    targets: {
    edge: "17",
    firefox: "60",
    chrome: "67",
    safari: "11.1"
    }
    }]
    ]
    //暴露(到导出)
    module.exports = { presets }
  • 在根目录新建一个index.js文件后,输入命令 npx babel-node ./index.js 即可运行。

设置默认导入导出

  • 默认导出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// m1.js文件
var a = 1;
var b = 2;
var c = 3;

function f() {
console.log('f函数');
}

export default {
a,
b,
f
};
  • 默认导入
1
2
3
4
5
import m1 from './m1.js'

console.log('运行成功!');
console.log(m1.a + ' ' + m1.b);
m1.f();

注意:在一个模块中,只允许使用export default向外默认暴露一次成员,千万不要写多个export default。

设置按需导入/导出

  • 按需导出
1
2
export let s1 = '111';
export let s2 = '222';
  • 按需导入
1
2
3
import { s1, s2 } from './m1.js'
console.log(s1);
console.log(s2);

直接导入并执行代码

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
    3
    npm 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
    3
    module.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
2
3
4
5
6
7
8
9
10
11
12
13
const path = require("path");
module.exports = {
mode:"development",
//设置入口文件路径
entry: path.join(__dirname,"./src/xx.js"),
//设置出口文件
output:{
//设置路径
path:path.join(__dirname,"./dist"),
//设置文件名
filename:"res.js"
}
}

设置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
    11
    module.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
    4
    module: { 
    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
    4
    const 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
    14
    module.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
    14
    module.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
    4
    module.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
    14
    module.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
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
28
29
30
31
32
33
34
35
36
<template> 
<!-- 这里用于定义Vue组件的模板内容 -->
</template>

<script>
// 这里用于定义Vue组件的业务逻辑
export default { data: () { return {} }, // 私有数据
methods: {} // 处理函数
// ... 其它业务逻辑
}
</script>
<style scoped>
/* 这里用于定义组件的样式 */
</style>

// 举例:App.vue文件
<template>
<div>
<p>根组件</p>
</div>
</template>

<script>
export default{
data(){
return {};
},
methods: {}
};
</script>

<style scoped>
p{
color: red;
}
</style>

配置.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
2
3
4
5
6
7
8
9
10
// 1. 导入 Vue 构造函数 
import Vue from 'vue'
// 2. 导入 App 根组件
import App from './components/App.vue'
const vm = new Vue({
// 3. 指定 vm 实例要控制的页面区域
el: '#app',
// 4. 通过 render 函数,把指定的组件渲染到 el 区域中
render: h => h(App)
});

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的默认构建方式和自定义方式;

20201028131432875.png

  • 这里我们选择自定义模式,在需要的选项按下空格即可选中,选完后按下回车进行确认;

20201028131432875.png

  • 接着选择你的版本(2.x/3.x),接着会让你选择是否使用历史模式,我们这里选择n,表示使用哈希模式;

20201028131432875.png

  • 接着是选择ESLint模式,这里选择Standard config
  • 然后让选择什么时候进行ESLint校验,默认选择Lint on save就好
  • 接着会询问那些工具的创建文件保存在单个文件还是一个总文件,这里选择默认的In dedicated config files
  • 最后会询问你是否将你的选择做成一个模版供后续使用,可以选择n

运行

  • 进入项目目录,执行npm run server即可运行项目

20201028131432875.png

  • 根据提示,复制http://localhost:8080/到浏览器中即可

方法二

  • 在需要创建项目的目录下,打开命令行输入

    1
    vue ui
  • 输入命令后会自动打开浏览器到可视化界面

20201028131432875.png

  • 点击创建新项目

20201028131432875.png

  • 预设,可以选择默认或自己的模版,这里以手动配置来学习(一定要选babel和Router以及Lint相关、使用配置文件开关)

  • 接着配置页面,默认的选项不用管,只需选择ESLint的Standard config模式

20201028131432875.png

  • 接着保存,你可以将其保存为一个模版,也可以不保存。然后确认即可开始创建项目;

20201028131432875.png

  • 创建完成后会出现如下面板,点击如下运行,可运行并管理项目。点击启动app可本地查看项目效果。

20201028131432875.png

项目结构分析

Vue脚手架产生的项目结构如下:

20201028131432875.png

  • node_modules 为依赖包目录
  • public 为静态资源目录
  • src为组件源码目录
  • babel.config.js 为babel的配置文件

Vue 脚手架的自定义配置

通过 package.json 配置项目

注意:不推荐使用这种配置方式。因为 package.json 主要用来管理包的配置信息;为了方便维护,推荐将 vue 脚手架相关的配置,单独定义到 vue.config.js 配置文件中。

1
2
3
4
5
6
7
// 必须是符合规范的json语法
"vue": {
"devServer": {
"port": "8888", // 端口号
"open" : true // 是否打开浏览器
}
},

通过单独的配置文件配置项目

  • 在项目的根目录创建文件 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
    18
    import 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文件中

20201028131432875.png 20201028131432875.png
  • 接着保存并运行项目

    1
    npm run serve
20201028131432875.png

基于图形化界面自动安装

  • 运行 vue ui 命令,打开图形化界面

  • 通过 Vue 项目管理器,进入具体的项目配置面板,方便演示这里新建一个项目,方法见上文。然后运行项目并启动app。

    20201028131432875.png
  • 点击 插件 -> 添加插件,进入插件查询面板

    20201028131432875.png
  • 搜索 vue-cli-plugin-element 安装

  • 配置插件,实现按需导入,从而减少打包后项目的体积

20201028131432875.png
  • 接着将按钮代码同样复制到目标文件中即可。