前端工程化&webpack

1.模塊化的相關規范

1.能夠了解
2.了解webpack
3.了解使用Vue單文件組件
4.能夠搭建Vue腳手架
5.掌握Element-UI的使用

1.模塊化的分類

1.1 瀏覽器端的模塊化

1).AMD(Asynchronous Module Definition,異步模塊定義)
代表產品為:Require.js
2).CMD(Common Module Definition,通用模塊定義)
代表產品為:Sea.js

1.2 服務器端的模塊化

服務器端的模塊化規范是使用CommonJS規范:

  • 模塊分為單文件模塊和包
  • 引入其他模塊:require('模塊標識符')
  • 導出模塊成員:exports或者module.exports
  • 一個文件就是一個模塊,擁有獨立的作用域

1.3 ES6模塊化

ES6模塊化規范中定義:

  • 每一個js文件都是獨立的模塊
  • 導入模塊成員:使用import關鍵字
  • 暴露模塊成員:使用export關鍵字

小結:推薦使用ES6模塊化,因為AMD,CMD局限使用于瀏覽器端,而CommonJS在服務器端使用

ES6模塊化是瀏覽器端和服務器端通用的規范

2.在NodeJS中安裝babel

2.1 安裝babel

babel的使用可以使得例如es6一些高級語法轉換為瀏覽器可以支持的語法

  • npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/node
  • npm install --save @babel/polyfill

2.2 創建babel.config.js

在項目根目錄中創建babel.config.js文件

編輯js文件中的代碼如下:

const presets = [
  [
    '@babel/env',
    {
      targets: {
        edge: '17',
        firefox: '60',
        chrome: '67',
        safari: '11.1'
      }
    }
  ]
]
module.exports = { presets }

2.3 創建index.js文件

在項目目錄中創建index.js文件作為入口文件

//index.js
       console.log("ok");

2.4 使用npx執行文件

? 打開vs終端(ctrl+`),輸入命令:npx babel-node ./index.js

3.設置默認導入/導出

3.1 默認導出

export default {
        成員A,
        成員B,
        .......
    }
let num = 100;
export default{
    num
}

3.2 默認導入

import 接收名稱 from "模塊標識符"
import test from "./test.js"

注意:在一個模塊中,只允許使用export default向外默認暴露一次成員,寫多個export default會報錯
如果在一個模塊中沒有向外暴露成員,其他模塊引入該模塊時將會得到一個空對象 {}

4.設置按需導入/導出

4.1 按需導出

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

4.2 按需導入

import 默認導入,{按需導入} from "導入模塊"
import { num,fn as printFn ,myName } from "./test.js"
//同時導入默認導出的成員以及按需導入的成員
import test,{ num,fn as printFn ,myName } from "./test.js"

注意:

  • 一個模塊中可以既有按需導入,也有默認導入,也可以按需導出和默認導出
  • 按需導入可以對導入重命名 ... as ...

5.直接導入并執行代碼

import "./test2.js";

6.webpack的概念

webpack是一個流行的前端項目構建工具,可以解決目前web開發的困境
webpack提供了模塊化支持,代碼壓縮混淆,解決js兼容問題,性能優化等特性,提高了開發效率和項目的可維護性

7.webpack的基本使用

7.1 創建項目目錄并初始化

創建項目空白目錄,運行npm init -y 命令,初始化包管理文件package.json

新建源代碼目錄src

7.2 創建首頁及js文件

? 在src中創建index.html頁面,并初始化頁面結構:在頁面中擺放一個ul,ul里面放置幾個li
? 在項目目錄中創建js文件夾,并在文件夾中創建index.js文件

7.3 安裝jQuery

npm install jQuery -S

7.4 導入jQuery

//index.js文件,編寫代碼導入jQuery并實現功能:
import $ from "jquery";
$(function(){
    $("li:odd").css("background","cyan");
    $("li:odd").css("background","pink");
})

注意:此時項目運行會有錯誤,因為import $ from "jquery";這句代碼屬于ES6的新語法代碼,在瀏覽器中可能會存在兼容性問題
所以我們需要webpack來幫助我們解決這個問題。

7.5 安裝webpack

  • 打開項目目錄,安裝webpack
npm install webpack webpack-cli -D
  • 在項目根目錄中,創建webpack.config.js 的配置文件

  • 初始化的基本配置如下:

module.exports = {
    mode:"development"http://可以設置為development(開發模式),production(發布模式)
}

注意:mode設置的是項目的編譯模式,development則表示項目處于開發階段,不會進行壓縮和混淆,打包速度會快,production則表示項目處于上線發布階段,會進行壓縮和混淆,打包速度會慢一些

  • 修改項目中的package.json文件,添加運行腳本dev
"scripts":{
    "dev":"webpack"
}

注意:scripts節點下的腳本,可以通過 npm run 運行,如:npm run dev 將會啟動webpack進行項目打包

  • 項目打包,并在頁面中引入打包生成的js文件

npm run dev運行后,找到默認的dist路徑中生成的main.js文件,將其引入到html頁面中,查看瀏覽頁面效果

8.設置webpack的打包入口/出口

在webpack 4.x中,

  • 默認打包入口js文件:src/index.js

  • 默認打包輸出js文件:dist/main.js

  • 自定義入口和出口文件:

    //webpack.config.js
    const path = require("path");
    module.exports = {
        mode:"development",
        //設置入口文件路徑
        entry: path.join(__dirname,"./src/index.js"),
        //設置出口文件
        output:{
            //設置輸出路徑
            path:path.join(__dirname,"./dist"),
            //設置輸出文件名
            filename:"res.js"
        }
    }
    

之后找到dist路徑中輸出的res.js文件,將其引入到html頁面<script src='./dist/res.js'></script>中,即可查看瀏覽頁面效果

問題:但是因為引入的是res.js,這樣每次修改index.js,就需要重新npm run dev打包一下,才能在瀏覽器看到新的效果

9.設置webpack的自動打包

自動打包可以解決以上繁瑣的操作,步驟如下:

  1. 安裝自動打包工具

    npm install webpack-dev-server -D
    
  2. 修改package.json中的dev指令

    "scripts":{
        "dev":"webpack-dev-server"
    }
    
  3. 更改引入的js文件路徑

    <script src="/bundle.js"></script>
    
  4. 打包

    npm run dev
    
  5. 打開網址查看效果:http://localhost:8080

    注意:
    webpack-dev-server會啟動一個實時打包的http服務器
    webpack-dev-server自動打包的輸出文件,默認放到了項目的根目錄中,是虛擬看不見的.

10.配置html-webpack-plugin

當訪問默認的 http://localhost:8080/,希望默認就能看到一個頁面,而不是看到目錄。 實現默認預覽頁面步驟如下:

  1. 安裝默認預覽功能的包

    npm install html-webpack-plugin -D
    
  2. 修改webpack.config.js

    //導入包
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    //創建對象
    const htmlPlugin = new HtmlWebpackPlugin({
        //設置生成預覽頁面的模板文件
        template:"./src/index.html",
        //設置生成的預覽頁面名稱
        filename:"index.html"
    })
    
  3. 繼續修改webpack.config.js,添加plugins信息

    module.exports = {
        ......
        plugins:[ htmlPlugin ]
    }
    
  4. 打包

    npm run dev
    
  5. 打開網址查看效果:http://localhost:8080

    補充:
    在自動打包完畢之后,自動打開瀏覽器網頁“--open”,配置ip “--host”,配置端口“--port”

    實現方式就是打開package.json文件,修改dev命令:

     "dev": "webpack-dev-server --open --host 127.0.0.1 --port 9999"
    

11.webpack中的加載器

默認情況下,webpack只能打包.js文件,如果想要打包非js文件,需要調用loader加載器才能打包

1、 loader加載器可以協助webpack打包處理特定的文件模塊 包含:

  • less-loader:可以打包處理.less相關的文件
  • sass-loader:可以打包處理.sass相關的文件
  • url-loader:打包處理css中與url路徑有關的文件
  • babel-loader:處理高級js語法的加載器
  • postcss-loader
  • css-loader,style-loader

2、loader的調用過程:

如果將要被webpack打包處理的文件

  • 不是js文件,也沒有配置對應的loader,會報錯;
  • 如果包含高級js,沒有配置babel,也報錯

11.1 打包處理css文件

  • 安裝包style-loader,css-loader

    npm install style-loader css-loader -D
    
  • 配置loader規則:更改webpack.config.js -> module -> rules數組

    module.exports = {
        ......
        plugins:[ htmlPlugin ],
        //所有第三方模塊的匹配規則
        module : {
            rules:[
                {
                    //test:匹配的文件類型,支持正則
                    test:/\.css$/,
                    //use:調用的loader
                    use:['style-loader','css-loader']
                }
            ]
        }
    }
    

    之后就可以在index.js中,import "./css/index.css"保存

  • 注意:

    use 數組指定loader的順序是固定的

    多個loader的調用順序是從后向前調用

11.2 打包處理less文件

  • 安裝less-loader,less

    npm install less-loader less -D
    
  • 配置loader規則:更改webpack.config.js -> module -> rules數組

    module.exports = {
        ......
        plugins:[ htmlPlugin ],
        module : {
            rules:[
                {
                    test:/\.css$/,
                    use:['style-loader','css-loader']
                },
                {
                    //test:匹配的文件類型,支持正則
                    test:/\.css$/,             
                    //use:調用的loader
                    use:['style-loader','css-loader','less-loader']
                }
            ]
        }
    }
    

    之后就可以在index.js中,import "./css/index.less"保存

11.3 打包處理scss文件

  • 安裝sass-loader,node-sass

    npm install sass-loader node-sass -D
    
  • 配置loader規則:更改webpack.config.js -> module -> rules數組

    module.exports = {
        ......
        plugins:[ htmlPlugin ],
        module : {
            rules:[
                {
                    test:/\.css$/,
                    use:['style-loader','css-loader']
                },
                {
                    test:/\.less$/,
                    use:['style-loader','css-loader','less-loader']
                },
                {
                    //test:匹配的文件類型,支持正則
                    test:/\.css$/,             
                    //use:調用的loader
                    use:['style-loader','css-loader','sass-loader']
                }
            ]
        }
    }
    

    之后就可以在index.js中,import "./css/index.scss"保存

11.4 自動添加css的兼容性前綴

  • 安裝post-css

    npm install postcss-loader autoprefixer -D
    
  • 在項目根目錄創建并配置postcss.config.js文件

    const autoprefixer = require("autoprefixer");//導入自動添加前綴的插件
    module.exports = {
        //掛載插件
        plugins:[ autoprefixer ]
    }
    
  • 配置loader規則:更改webpack.config.js -> module -> rules數組

    module.exports = {
        ......
        plugins:[ htmlPlugin ],
        module : {
            rules:[
                {
                    test:/\.css$/,
                    //添加postcss-loader
                    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']
                }
            ]
        }
    }
    

    之后就可以在index.js中,import "./css/index.css"保存(這樣ie也能顯示相同效果)

    /*index.css*/
    ::placeholder {
      color: red;
    }
    

11.5 打包樣式表中的圖片以及字體文件

在樣式表css中有時候會設置背景圖片和設置字體文件,一樣需要loader進行處理

  • 安裝包url-loader file-loader(file-loader是url-loader 的內置)

    npm install url-loader file-loader -D
    
  • 配置loader規則:更改webpack.config.js -> module -> rules數組

    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圖片
                    //大于或等于時 不會轉成base64圖片
                    use:"url-loader?limit=16940"
                }
            ]
        }
    }
    

    之后就可以在index.js中,import "./css/index.css"保存(這樣圖片就能加載出來)

    /*index.css*/
    ::placeholder {
      color: red;
    }
    #div {
        width: 500px;
        height: 340px;
        background: url('../images/1.jpg');
    }
    

11.6 打包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" ]
    }
    
  • 配置loader規則:更改webpack.config.js -> module -> rules數組

    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/
                }
            ]
        }
    }
    

12.Vue單文件組件

傳統Vue組件的缺陷:

  • 全局定義的組件不能重名,字符串模板缺乏語法高亮,不支持css(當html和js組件化時,css沒有參與其中)
  • 沒有構建步驟限制,只能使用H5和ES5,不能使用預處理器(babel)

解決方案:

  • 使用Vue單文件組件,每個單文件組件的后綴名都是.vue
  • 每一個Vue單文件組件都由三部分組成:
    • template組件組成的模板區域
    • script組成的業務邏輯區域
    • style樣式區域

代碼如下:**.vue文件

<template>
    組件代碼區域
</template>

<script>
    js代碼區域
</script>

<style scoped>
    /*scoped使得每個組件中的樣式是私有的,不沖突*/
    樣式代碼區域
</style>

補充:安裝Vetur插件可以使得.vue文件中的代碼高亮

配置.vue文件的加載器

接著,配置.vue文件的加載器,從而可以打包.vue單文件組件

  • 安裝vue組件的加載器
npm install vue-loader vue-template-compiler -D
  • 配置loader規則:更改webpack.config.js -> module -> rules數組
const VueLoaderPlugin = require("vue-loader/lib/plugin");
const vuePlugin = new VueLoaderPlugin();
module.exports = {
    ......
    plugins:[ htmlPlugin, vuePlugin  ],
    module : {
        rules:[
            ...//其他規則
            { 
                test:/\.vue$/,
                loader:"vue-loader",
            }
        ]
    }
}

13.在webpack中使用vue

上一節我們安裝處理了vue單文件組件的加載器,想要讓vue單文件組件能夠使用,我們必須要安裝vue,并使用vue來引用vue單文件組件

  • 安裝Vue

    npm install vue -S
    
  • 在index.js中引入vue

    import Vue from "vue"
    // 導入單文件組件
    import App from './components/App.vue'
    //創建Vue實例對象并指定el
    const vm = new Vue({
        el:"#first",
        //使用render函數渲染單文件組件
        render:h=>h(app)
    })
    

14.使用webpack打包發布項目

在項目上線之前,我們需要將整個項目打包并發布。

  1. 配置package.json
"scripts":{
    "dev":"webpack-dev-server",
    //
    "build":"webpack -p"
}
  1. 在項目打包之前,可以將dist目錄刪除,生成全新的dist目錄

15.Vue腳手架

Vue腳手架可以快速生成Vue項目基礎的架構

15.1 安裝3.x版本的Vue腳手架

npm install -g @vue/cli

15.2 創建Vue項目

(1)基于交互式命令行的方式

vue create my-project
選擇Manually select features(手動選擇特性以創建項目)
用空格進行勾選(比如用到了babel router linter)
是否選用歷史模式的路由:n(此時選擇的是哈希形式的路由)
ESLint選擇:ESLint + Standard config
何時進行ESLint語法校驗:Lint on save(默認)
babel,postcss等配置文件如何放置:In dedicated config files(單獨使用文件進行配置)
是否保存當前這些配置為模板:n
使用哪個工具安裝包:npm

(2)基于圖形化界面

命令:vue ui
    在自動打開的創建項目網頁中配置項目信息,同上面

(3)基于2.x的舊模板,創建Vue項目
npm install -g @vue/cli-init
vue init webpack my-project

15.3 分析Vue腳手架生成的項目結構

  • node_modules:依賴包目錄
  • public:靜態資源目錄
  • src:源碼目錄
    • src/assets:資源目錄(樣式表 樣式圖片)
    • src/components:組件目錄
    • src/views:視圖組件目錄
    • src/App.vue:根組件
    • src/main.js:打包入口js
    • src/router.js:路由js
  • babel.config.js:babel配置文件
  • .eslintrc.js:eslintrc語法配置文件
  • .gitignore:git忽略文件
  • package.json:包管理文件
  • postcss.config.js:配置前綴文件

16.Vue腳手架的自定義配置

? A.通過 package.json 進行配置 [不推薦使用]

"vue":{
    "devServer":{
        "port":"9990",
        "open":true
    }
}

? B.通過單獨的配置文件進行配置,在項目根目錄創建vue.config.js

module.exports = {
    devServer:{
        port:8888,
        open:true
    }
}

17.Element-UI的基本使用

Element-UI:為開發者提供的一套基于2.0的桌面端組件庫,官網地址:http://element-cn.eleme.io/#/zh-CN

A.安裝:

npm install element-ui -S

B.在入口函數main.js 導入使用:

import ElementUI from "element-ui";//導入組件庫
import "element-ui/lib/theme-chalk/index.css";//導入組件樣式
Vue.use(ElementUI);//配置vue插件

之后可以根據官方文檔復制代碼修改樣式,使用相應的組件

基于圖形化界面 自動安裝Element-UI:

vue ui
Vue項目管理器,進入到項目配置面板
點擊插件 -> 添加插件,進入插件查詢面板
搜索并安裝vue-cli-plugin-element
配置插件,實現按需導入,從而減少打包后項目的體積
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370