前端学习之前端工程化(一):ES6模块化和webpack打包

一、前端工程化:

1. 模块化相关规范:

1.1 模块化概要:

  • 传统开发模式的主要问题:
    • 命名冲突;
    • 文件依赖;

模块化:

  • 把单独的一个功能封装到一个模块(文件)中, 模块之间相互隔离, 但是可以通过特性的接口公开内部成员, 也可以依赖别的模块;
  • 模块化开发的好处: 方便代码重用 从俄日提升开发效率, 并且方便后期维护;

1.2 浏览器模块化规范:

AMD:

Require.js: http://www.requirejs.cn/

在这里插入图片描述

CMD:

Sea.js: https://sea.js.github.io/seajs/docs
在这里插入图片描述

1.3 服务端的模块化规范:

CommonJS规范:

  • 使用require引入其他模块或者;
  • 使用exports或者module.exports导出模块成员;
  • 一个文件就是一个模块,都拥有独立的作用域;

1.4 大一统的ES6规范:

在ES6模块化规范诞生之前, JavaScript社区已经尝试并提出了AMD, CMD,CommonJS等模块化规范;但是, 这些规范还存在一定的差异性与局限性, 并不是浏览器与服务端通用的模块化标准; 因此,ES6语法规范,在语言层面生定义了ES6模块化规范, 是浏览器与服务端通用的模块化开发规范;

  • ES6模块化规范中定义:
    • 每一个js文件都是独立的模块
    • 导入模块成员使用import关键字
    • 暴露模块成员使用export关键字

2. Node.js中通过babel体验ES6模块化:

  • babel: 语法转化模块, 将符合ES6规范的JavaScript代码,转化成基础的JavaScript代码;

2.1 安装与配置babel:

  • 安装babel:
npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/node
npm install --save @babel/polyfill
  • 在项目的根目录创建文件babel.config.js
  • babel.config.js文件的内容:
const presets = [
    ["@babel/env",{
        targets:{
        	//浏览器版本
            edge:"17",
            firefox:"60",
            chrome:"67",
            safari:"11.1"
        }
    }]
]
//暴露
module.exports = { presets }
  • 创建index.js文件:
    在项目目录中创建index.js文件作为入口文件
    在index.js中输入需要执行的js代码,例如:
console.log("ok");
  • 通过npx babel-node index.js执行代码;

3. 设置默认导入/导出:

注意:
在一个模块中,只允许使用export default向外默认暴露一次成员,千万不要写多个export default。
如果在一个模块中没有向外暴露成员,其他模块引入该模块时将会得到一个空对象

3.1 默认导出:

默认导出语法:

export default {
    成员A,
    成员B,
    .......
}

例如:

// m1.js
function show() {}
let num = 100;
export default{
    num,
    show
}

3.2 默认导入:

默认导入语法:

import m1 from './m1.js'

console.log(m1);
// {num: 100, show: [Function: show]}

4.设置按需导入/导出:

4.1 按需导出:

按需导出语法::

export let s1 = 10

例如:

// m1.js

export let num = 998;
export let myName = "jack";
export function fn = function(){ console.log("fn") }

4.2 按需导入:

按需导入语法:

import { s1 } from '模块标识符'

例如:

import { num,fn as printFn ,myName } from "./test.js"
//同时导入默认导出的成员以及按需导入的成员
import test,{ num,fn as printFn ,myName } from "./test.js"

5. 直接导入并执行代码:

语法:

import "./test2.js";

例如:

// m1.js
console.log("oooooooo")

// m2.js
import "./m1.js";

二、webpack:

1. 当前web开发面临的困境:

  • 文件依赖关系错综复杂;
  • 静态资源请求效率低;
  • 模块化支持不好;
  • 浏览器对于高级的JavaScript特性兼容程度比较低;
  • 。。。

2. webpack:

  • webpack是一个流行的前端项目构建工具(打包工具),可以解决目前web开发的困境;
  • webpack提供了模块化支持,代码压缩混淆,解决js兼容问题,性能优化等特性,提高了开发效率和项目的可维护性

在这里插入图片描述

3. webpack基本使用:

3.1 基本流程:

  • 新建项目空白目录, 并运行npm init -y命令, 初始化包管理配置文件 package.json;
  • 新建src源代码目录;
  • 新建 src -> index.html首页;
  • 初始化首页基本的结构;
  • 运行npm install jquery -S命令, 安装jQuery
  • 通过模块化形式, 实现列表各行变色的效果;

目录结构

01_base
├─node_modules 
│  └─jquery
├─src
│  ├─index.js
│  ├─index.html
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>隔行变色</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>
// index.js
import $ from 'jquery'

$(function() {
    $('li:odd').css('backgroundColor',  'pink');
    $('li:even').css('backgroundColor',  'lightblue')
})

3.2 使用webpack修复3.1问题:

  • 运行npm install webpack webpack-cli -D命令安装, 安装webpack相关包;
  • 在项目根目录中, 创建名称 webpack.config.js的webpack配置文件;
  • 在webpack的配置文件中红,初始化如下基本配置:
module.export = {
	mode: 'development' // 可以设置为development(开发模式),production(发布模式)
}
  • 补充:mode设置的是项目的编译模式。
    • 如果设置为development则表示项目处于开发阶段,不会进行压缩和混淆,打包速度会快一些
    • 如果设置为production则表示项目处于上线发布阶段,会进行压缩和混淆,打包速度会慢一些
  • package.json配置文件中的scripts节点线下, 新增dev脚本如下:
"scripts": {
	"dev": "webpack"	//scripts节点下的脚本, 可以通npm run执行
}
  • 在终端执行npm run dev命令, 启动webpack进行项目打包.
  • index.html中对index.js的引用修改成dist/main.js的引用

4. 设置webpack的打包入口/出口:

  • 在webpack 4.x中,默认会将src/index.js作为默认的打包入口js文件默认会将dist/main.js作为默认的打包输出js文件;
  • 如果不想使用默认的入口/出口js文件,可以通过改变 webpack.config.js来设置入口/出口的js文件,如下:
const path = require("path");	// 导入node.js中专门操作路径的模块
module.exports = {
    mode:"development",
    //设置入口文件路径
    entry: path.join(__dirname,"./src/index.js"),
    //设置出口文件
    output:{
        //设置路径
        path:path.join(__dirname,"./dist"),
        //设置文件名
        filename:"bundle.js"
    }
}
  • dit目录下生成了bundle.js, 将index.html中的js引用替换成bundle.js;

5. 配置webpack的自动打包功能:

  • 运行npm install webpack-dev-server -D命令, 安装支持项目自动打包的工具;
  • 修改package.json -> scripts中dev命令, 如下:
"scripts":{
   "dev":"webpack-dev-server"
}
  • src -> index,html中, script 脚本的引用路径修改为/buldle.js
  • 运行npm run dev命令, 重新进行打包;
  • 在浏览器中访问http://127.0.0.1:8080地址, 查看自动打包效果;
    • 注意:
      • webpack-dev-server会启动一个实时打包的http服务器;
      • webpack-dev-server自动打包的输出文件,默认放到了服务器的根目录中;
      • 在自动打包完毕之后,默认打开服务器网页,实现方式就是打开package.json文件,修改dev命令:
      "scripts":{
      	"dev": "webpack-dev-server --open --host 127.0.0.1 --port 80"
      	}
      

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6. 配置html-webpack-plugin, 生成预览页面:

  • 运行npm install html-webpack-plugin -D命令, 安装生成预览页面的插件;
  • 修改webpack.config.js文件头部区域, 添加如下配置:
 //导入生成预览页面的插件, 得到一个构造函数
const HtmlWebpackPlugin = require("html-webpack-plugin");
//创建对象
const htmlPlugin = new HtmlWebpackPlugin({
    //指定生成预览页面的模板文件
    template:"./src/index.html",
    //设置生成的预览页面名称, 该文件将存在于内存中
    filename:"index.html"
})
  • 修改webpack.config.js文件,添加plugins信息:
module.exports = {
   ......
    plugins:[ htmlPlugin ]	// plugins数组是webpack打包区间会用到的一些插件列表
}

在这里插入图片描述

7. webpack中的加载器:

7.1 通过loader打包费js模块:

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

7.2 loader加载器:

  • loader加载器可以协助webpack打包处理特定的文件模块:
    - less-loader: 可以处理.less相关的文件
    - sass-loader: 可以处理.scee相关的文件
    - url-loader: 打包处理css中与url路径有关的文件
    - babel-loader: 处理高级js语法的加载器
    - postcss-loader
    - css-loader,style-loader

7.3 loader的调用过程:

在这里插入图片描述

7.4 webpack中接在其的基本使用:

在这里插入图片描述

  • css
  • less
  • scss
  • postcss
  • JavaScript
  • image/font
  • Vue

7.5 打包处理css文件:

  • 运行npm install style-loader css-loader -D命令, 女装处理css文件的loader;
  • webpack.config.jsmodule -> rules数组中添加loader规则如下:
module.exports = {
   ......
    plugins:[ htmlPlugin ],
    module : {
        rules:[
            {
                //test设置需要匹配的文件类型,支持正则
                test:/\.css$/,
                //use表示该文件类型需要调用的loader
                use:['style-loader','css-loader']
            }
        ]
    }
}
  • 注意:
    • use 数组中指定的loader顺序是固定的;
    • 多个 loader 的调用顺序是从后往前调用;

7.6 打包处理less文件:

  • 运行npm install less-loader less -D命令;
  • webpack.config.jsmodule -> rules数组中添加loader规则如下:
 module.exports = {
   ......
   plugins:[ htmlPlugin ],
   module : {
       rules:[
           {test:/\.css$/, use:['style-loader','css-loader']},
           {test:/\.less$/, use:['style-loader','css-loader','less-loader']}
       ]
   }
}
  • index.js中引用.less文件;

7.7 打包处理scss文件:

  • 运行npm install sass-loader node-sass -D命令;
  • webpack.config.jsmodule -> rules数组中添加loader规则如下:
module.exports = {
    ......
    plugins:[ htmlPlugin ],
    module : {
        rules:[
            { test:/\.css$/, use:['style-loader','css-loader'] },
            { test:/\.less$/, use:['style-loader','css-loader','less-loader'] },
            { test:/\.scss$/, use:['style-loader','css-loader','sass-loader'] }
        ]
    }
}

7.8 配置postCSS, 自动添加css的兼容前缀:

  • 运行npm install postcss-loader autoprefixer -D命令;
  • 在项目中创建postcss的配置文件postcss.config.js, 并初始化一下内容:
const autoprefixer = require("autoprefixer");	// 导入自动添加前缀的插件
module.exports = {
    plugins:[ autoprefixer ]	// 挂载插件
}
  • webpack.config.jsmodule -> rules数组中修改loader规则如下:
module.exports = {
    ......
    plugins:[ htmlPlugin ],
    module : {
        rules:[
            {
                //test设置需要匹配的文件类型,支持正则
                test:/\.css$/,
                //use表示该文件类型需要调用的loader
                use:['style-loader','css-loader','postcss-loader']
            },	
        ]
    }
}

7.9 打包样式表中的图片和字体文件:

  • 运行命令npm install url-loader file-loader -D命令;
  • webpack.config.jsmodule -> rules数组中添加loader规则如下:
module.exports = {
    ......
    plugins:[ htmlPlugin ],
    module : {
        rules:[
            { test:/\.css$/, use:['style-loader','css-loader'] },
            { test:/\.less$/, use:['style-loader','css-loader','less-loader'] },
            { test:/\.scss$/,  use:['style-loader','css-loader','sass-loader'] },
            { 
            	test:/\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/,
                //limit用来设置字节数,只有小于limit值的图片,才会转换为base64图片
                use:"url-loader?limit=16940"
            }
        ]
    }
}

7.10 打包js文件中的高级语法:

在编写js的时候,有时候会使用高版本的js语法;
有可能这些高版本的语法不被兼容,需要将之打包为兼容性的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文件:
module.exports = {
   presets:["@babel/preset-env"],
   plugins:[ "@babel/plugin-transform-runtime", "@babel/plugin-proposal-class-properties" ]
}

webpack.config.jsmodule -> rules数组中添加loader规则如下:

module.exports = {
    ......
    plugins:[ htmlPlugin ],
    module : {
        rules:[
            { test:/\.css$/, use:['style-loader','css-loader'] },
            { test:/\.less$/, use:['style-loader','css-loader','less-loader'] },
            { test:/\.scss$/, use:['style-loader','css-loader','sass-loader'] },
            { test:/\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/, use:"url-loader?limit=16940" },
            {
                test:/\.js$/,
                use:"babel-loader",
                //exclude为排除项,意思是不要处理node_modules中的js文件
                exclude:/node_modules/
            }
        ]
    }
}

三、Vue单文件组件:

1. 传统组件的问题和解决方案:

1.1 问题:

  • 全局定义的组件必须保证组件的名称不重复;
  • 字符串模板缺乏语法高亮, 在html有多行的时候,需要用到;
  • 不支持css意味着当html和JavaScript组件化时, css明显被遗漏;
  • 没有构建步骤的限制, 只能使用html和es5 JavaScript, 而不能使用预处理器(如:babel);

1.2 解决:

使用Vue单文件组件,每个单文件组件的后缀名都是.vue

每一个Vue单文件组件都由三部分组成:

  • template组件组成的模板区域;
  • script组成的业务逻辑区域;
  • style样式区域;
<template>

    组件代码区域

</template>

<script>

    js代码区域

</script>

<style scoped>

    样式代码区域

</style>

2. webpack配置.vue文件的加载器

  • 运行npm install vue-loader vue-template-compiler -D命令, 安装vue的loader;
  • webpack.config.js配置文件中, 添加vue-loader的配置项, 如下:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const htmlPlugin = new HtmlWebpackPlugin({ template:"./src/index.html", filename:"index.html" });
const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
    mode:"development",
    entry: path.join(__dirname,"./src/index.js"),
    output:{
        path:path.join(__dirname,"./dist"),
        filename:"bundle.js"
    },
    plugins:[ htmlPlugin, new VueLoaderPlugin(), ],
    module : {
        rules:[
            { test:/\.css$/, use:['style-loader','css-loader','postcss-loader'] },
            { test:/\.less$/, use:['style-loader','css-loader','less-loader'] },
            { test:/\.scss$/, use:['style-loader','css-loader','sass-loader'] },
            { test:/\.jpg|png|gif|bmp|ttf|eot|svg|woff|woff2$/, use:"url-loader?limit=169400" },
            { test: /\.vue$/, use: 'vue-loader'},
        ]
    }
}
  • 注意:
    • 实现时遇到了最新版的vue-loader找不到vue-loader/lib/plugin, 解决办法: 将vue-load版本更换为"vue-loader": "^15.7.0"

3. 在webpack项目中使用vue:

  • 运行npm install vue -S安装 vue;
  • src -> index.js入口文件中, 通过import Vue from 'vue'来带入vue构造函数;
  • 创建Vue实例对象, 并制定要控制的el区域;
  • 通过 render函数渲染App根组件:
// index.js
import Vue from 'vue'
import App from './components/App.vue'

const vm = new Vue({
	el: '#app',
	render: h => h(App)
})
  • 注意:
    • 此处(index.js)中导入的vue是一个阉割版的vue, 只支持使用render来渲染组件, 不支持components 、template等属性;

4. 使用webpack打包发布项目:

在项目上线之前,我们需要将整个项目打包并发布。

  • 配置package.json
"scripts":{
	"dev":"webpack-dev-server",
	"build":"webpack -p"
}
  • 在项目打包之前,可以将dist目录删除,生成全新的dist目录
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章