Vue.js學習筆記(二)

4、模組化開發

ES6模組化的匯入和匯出

  • 我們使用export指令匯出了模組對外提供的介面,下面我們就可以通過import命令來載入對應的這個模組了
  • 首先,我們需要在HTML程式碼中引入兩個js檔案,並且型別需要設定為module
  • import指令用於匯入模組中的內容.比如main.is的程式碼

匯出方法:

  1. var name = '小明';
  2. var age = 18;
  3. var flag = true;
  4. function sum(num1, num2) {
  5. return num1 + num2
  6. }
  7. if (flag) {
  8. console.log(sum(20, 30));
  9. }
  10. // 1.匯出方式一:
  11. export{
  12. flag,sum
  13. }
  14. // 2.匯出方式二:
  15. export var num1 = 100;
  16. export var height = 1.88;
  17. // 3.匯出函式/類
  18. export function mul(num1,num2){
  19. return num1+num2
  20. }
  21. export class Person{
  22. run(){
  23. console.log('再跑');
  24. }
  25. }
  26. // 5.export default
  27. // 某些情況下, 一個模組中包含某個的功能,我們並不希望給這個功能命名,而且讓匯入者可以自己來命名,只能有一個
  28. // const address = "北京市";
  29. // export default address;
  30. export default function(argument){
  31. console.log(argument);
  32. }

匯入方法:

  1. // 1.匯入的{}中定義的變數
  2. import {flag,sum} from "./aaa.js";
  3. if(flag){
  4. console.log("小明666");
  5. console.log(sum(20,30));
  6. }
  7. // 2.直接匯入export定義的變數
  8. import{num1,height} from "./aaa.js";
  9. console.log(num1);
  10. console.log(height);
  11. // 3.匯入 export的function/class
  12. import{mul,Person} from "./aaa.js";
  13. console.log(mul(1000,100))
  14. const p = new Person();
  15. p.run();
  16. // 4.匯入export default中的內容
  17. import addr from "./aaa.js";
  18. addr('你好');
  19. // 5.同一全部匯入
  20. import * as aaa from "./aaa.js";
  21. console.log(aaa.flag)

5、Webpack

一、什麼是webpack

前端模組化:

  • 在前面學習中,我已經用了大量的篇幅解釋了為什麼前端需要模組化。
  • 而且我也提到了目前使用前端模組化的一些方案: AMD、CMD、CommonJS、 ES6。
  • 在ES6之前,我們要想進行模組化開發,就必須藉助於其他的工具,讓我們可以進行模組化開發。
  • 並且在通過模組化開發完成了專案後,還需要處理模組間的各種依賴,並且將其進行整合打包。
  • 而webpack其中一個核心就是讓我們可能進行模組化開發 ,並且會幫助我們處理模組間的依賴關係。而且不僅僅是JavaScript檔案,我們的CSS、圖片、json檔案等等在webpack中都可以被當做模組來使用(在後續我們會看到)。
  • 這就是webpack中模組化的概念。

打包如何理解呢?

  • 理解了webpack可以幫助我們進行模組化,並且處理模組間的各種複雜關係後,打包的概念就非常好理解了。
  • 就是將webpack中的各種資源模組進行打包合併成一個或多個包(Bundle)。
  • 並且在打包的過程中,還可以對資源進行處理比如壓縮圖片,將scss轉成css ,將ES6語法轉成ES5語法,將TypeScript轉成JavaScript等等操作.

二、webpack安裝

準備工作

  • 我們建立如下檔案和資料夾:
  • 檔案和資料夾解析:
    • dist資料夾:用於存放之後打包的檔案
    • src資料夾:用於存放我們寫的原始檔
      • main.js :專案的入口檔案。具體內容檢視下面詳情。
      • mathUtils.js :定義了一 -些數學工具函式 ,可以在其他地方引用,並且使用。具體內容檢視下面的詳情。
    • index.html :瀏覽器開啟展示的首頁html
    • package.json :通過npm init生成的, npm包管理的檔案
  • mathUtils.js檔案中的程式碼:
  • main.js檔案中的程式碼:

JS檔案的打包

  • 現在的js檔案中使用了模組化的方式進行開發,他們可以直接使用嗎?不可以。

    • 因為如果直接在index.htmI引入這兩個js檔案,瀏覽器並不識別其中模組化程式碼。
    • 外,在真實專案中當有許多這樣的js檔案時,我們一個個引用非常麻煩,並且後期非常不方便對它們進行管理。
  • 我們應該怎麼做呢?使用webpack工具,對多個js檔案進行打包。
    • 我們知道, webpack就是一個模組化的打包工墾 ,所以它支援我們程式碼中寫模組化,可以對模組化的程式碼進行處理。( 如何處理的,待會兒在原理中, 我會講解)
    • 另外,如果在處理完所有模組之間的關係後,將多個js打包到一個js檔案中 ,引入時就變得非常方便了。
  • OK ,如何打包呢?使用webpack的指令即可
  1. webpack ./src/main.js ./dist/bundle.js

  • 打包後會在dist檔案下,生成一個bundle.js檔案

    • 檔案內容有些複雜,這裡暫時先不看,後續再進行分析。
    • bundle.js檔案,是webpack處理了專案直接檔案依賴後生成的一個js檔案,我們只需要將這個js檔案在index.htmlI中引入即可

webpack.config.js和package.json的配置

webpack.config.js可以配置webpack的出入口

  1. //引用node的基本包
  2. const path = require('path');
  3. // 指定webpack的出入口
  4. module.exports = {
  5. entry: './src/main.js',
  6. output: {
  7. // 動態獲取路徑 絕對路徑
  8. path: path.resolve(__dirname,'dist'),
  9. filename: 'bundle.js'
  10. },
  11. }

package.json配置node指令碼和依賴

  1. {
  2. "name": "meetwebpack",
  3. "version": "1.0.0",
  4. "description": "",
  5. "main": "index.js",
  6. "scripts": {
  7. "test": "echo \"Error: no test specified\" && exit 1",
  8. "build": "webpack" //npm run build 執行本地webpack而不是全域性webpack
  9. },
  10. "author": "",
  11. "license": "ISC",
  12. "dependencies": {},
  13. "devDependencies": {
  14. "webpack": "^3.6.0" //所依賴的webpack版本
  15. }
  16. }

區域性安裝webpack

  1. npm install webpack@3.6.0 --save-dev

三、Loader

  • loader是webpack中一個非常核心的概念。

  • webpack用來做什麼呢?

    • 在我們之前的例項中,我們主要是用webpack來處理我們寫的js程式碼,並且webpack會自動處理js之間相關的依賴。
    • 但是,在開發中我們不僅僅有基本的js程式碼處理,我們也需要載入css、圖片,也包括一些高階的將ES6轉成ES5程式碼,將TypeScript轉成ES5程式碼,將scss、less轉成css ,將jsx、.vue檔案轉成js檔案等等。
    • 對於webpack本身的能力來說,對於這些轉化是不支援的。
    • 那怎麼辦呢?給webpack擴充套件對應的loader就可以啦。
  • loader使用過程:

    • 步驟一 : 通過npm安裝需要使用的loader

    • 步驟二 : 在webpack.config.js中的modules關鍵字下進行配置

  • 大部分loader我們都可以在webpack的官網中找到,並且學習對應的用法。

CSS和LESS檔案處理

  • 專案開發過程中,我們必然需要新增很多的樣式,而樣式我們往往寫到一個單獨的檔案中。

    • 在src目錄中,建立一個css檔案 ,其中建立一個normal.css檔案。

    • 我們也可以重新組織檔案的目錄結構,將零散的js檔案放在一個js資料夾中。

  • normal.css中的程式碼非常簡單,就是將body設定為red

  • 但是,這個時候normal.css中的樣式會生效嗎?

    • 當然不會,因為我們壓根就沒有引用它。
    • webpack也不可能找到它,因為我們只有一個入口, webpack會從入口開始查詢其他依賴的檔案。

mian.js

  1. // 1. 使用commonjs的模組化規範
  2. const {add, mul} = require('./js/mathUtils.js')
  3. console.log(add(20,30));
  4. console.log(mul(20,30));
  5. // 2.使用ES6的模組化規範
  6. import { name,age,height} from './js/info.js';
  7. console.log(name);
  8. console.log(age);
  9. console.log(height);
  10. // 3.依賴css檔案
  11. require('./css/normal.css')
  12. // 4.依賴less檔案
  13. require('./css/special.less')
  14. document.writeln('<h2>你好<h2>')

在webpack裡面找到CSS的loader

安裝css-loader css-loader只負責將css檔案進行載入

  1. npm install --save-dev css-loader

安裝style-loader style-loader 把CSS樣式插入到DOM中

  1. npm install --save-dev style-loader

使用多個loader時,是從右向左

webpack.config.js的配置

  1. const path = require('path');
  2. // 指定webpack的出入口
  3. module.exports = {
  4. entry: './src/main.js',
  5. output: {
  6. // 動態獲取路徑 絕對路徑
  7. path: path.resolve(__dirname, 'dist'),
  8. filename: 'bundle.js'
  9. },
  10. module: {
  11. rules: [{
  12. test: /\.css$/i,
  13. // css-loader只負責將css檔案進行載入
  14. // style-loader 把CSS樣式插入到DOM中
  15. // 使用多個loader時,是從右向左
  16. use: ["style-loader", "css-loader"],
  17. },
  18. {
  19. test: /\.less$/,
  20. use: [{
  21. loader: "style-loader" // creates style nodes from JS strings
  22. }, {
  23. loader: "css-loader" // translates CSS into CommonJS
  24. }, {
  25. loader: "less-loader" // compiles Less to CSS
  26. }]
  27. }
  28. ],
  29. },
  30. }

圖片檔案處理

安裝url-loader

  1. npm install --save-dev url-loader

如果大於limit就要安裝file-loader

  1. npm install --save-dev file-loader

配置webpack.config.js

  1. {
  2. test: /\.(png|jpg|gif|jpeg)$/,
  3. use: [{
  4. loader: 'url-loader',
  5. options: {
  6. // 當載入圖片時,小於limit時,會將圖片編譯成base64字串形式。
  7. // 當載入圖片時,大於limit時,需要使用file-loader模組進行載入。
  8. limit: 13000,
  9. name:'img/[name].[hash:8].[ext]' //使圖片全部儲存在dist的img資料夾裡且命名為 原來名字+8位hash值(防止重複)+.原來字尾
  10. },
  11. }]
  12. }

再次打包後dist資料夾會出現一個圖片檔案

  • 我們發現webpack自動幫助我們生成- 個非常長的名字

    • 這是一個32位hash值,目的是防止名字重複
    • 但是,真實開發中,我們可能對打包的圖片名字有一定的要求
    • 比如,將所有的圖片放在一個資料夾中,跟上圖片原來的名稱,同時也要防止重複
  • 所以,我們可以在options中新增上如下選項:
    • img:檔案要打包到的資料夾
    • name :獲取圖片原來的名字,放在該位置
    • hash:8 :為了防止圖片名稱衝突,依然使用hash ,但是我們只保留8位
    • ext :使用圖片原來的副檔名、
  • 但是,我們發現圖片並沒有顯示出來,這是因為圖片使用的路徑不正確
    • 預設情況下, webpack會將生成的路徑直接返回給使用者
    • 但是,我們整個程式是打包在dist資料夾下的,所以這裡我們需要在路徑下再新增一個dist/

ES6語法處理

如果你仔細閱讀webpack打包的jis檔案,發現寫的ES6語法並沒有轉成ES5 ,那麼就意味著可能一 些對ES6還不支援的瀏覽器沒有辦法很好的執行我們的程式碼。

在前面我們說過,如果希望將ES6的語法轉成ES5 ,那麼就需要使用babel。

  • 而在webpack中,我們直接使用babel對應的loader就可以了。

    1. npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
  • 配置webpack.config.js檔案

    1. {
    2. test: /\.m?js$/,
    3. exclude: /(node_modules|bower_components)/,
    4. use: {
    5. loader: 'babel-loader',
    6. options: {
    7. presets: ['es2015']
    8. }
    9. }
    10. },

Webpack配置Vue

  1. npm安裝vue

    1. npm install vue --save
  2. 依賴引入vue並使用

  3. 指定vue的版本

  • runtime-only 版本->程式碼中,不可以有任何的template
  • runtime-compiler 版本 >程式碼中,可以有template,因為有compiler可以用於編譯template

在webpack.config.js中配置

  1. resolve: {
  2. alias: {
  3. 'Vue$': 'vue/dist/vue.esm.js'
  4. }
  5. }

el和template區別

定義template屬性:

  • 在前面的Vue例項中,我們定義了el屬性,用於和index.htmI中的#app進行繫結,讓Vue例項之後可以管理它其中的內容

  • 這裡,我們可以將div元素中的{message}}內容刪掉,只保留一個基本的id為div的元素

  • 但是如果我依然希望在其中顯示{{message}}的內容,應該怎麼處理呢?

  • 我們可以再定義一個template屬性 ,程式碼如下:

    1. new Vue({
    2. el: '#app',
    3. template: `
    4. <div>
    5. <h1>{{message}}</h1>
    6. </div>
    7. `,
    8. data: {
    9. message: 'Hello Webpack'
    10. }
    11. })

.vue檔案的處理

從html中寫vue程式碼->main.js中寫vue程式碼->vue.js中寫vue程式碼

main.js中寫vue程式碼

  1. // 5.使用vue進行開發
  2. import Vue from 'Vue'
  3. new Vue({
  4. el: '#app',
  5. template: `
  6. <div>
  7. <h1>{{message}}</h1>
  8. </div>
  9. `,
  10. data: {
  11. message: 'Hello Webpack'
  12. }
  13. })

進行抽離獨立出來App.js

  1. export default {
  2. template: `
  3. <div>
  4. <h1>{{message}}</h1>
  5. </div>
  6. `,
  7. data() {
  8. return {
  9. message: 'Hello Webpack11'
  10. }
  11. }
  12. }

進一步抽離 Vue.js中寫vue程式碼

Vue.js

  1. <template>
  2. <div>
  3. <h1>{{ message }}</h1>
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. data() {
  9. return {
  10. message: "Hello Webpack11",
  11. };
  12. },
  13. components: {},
  14. computed: {},
  15. methods: {},
  16. };
  17. </script>
  18. <style scoped>
  19. h1 {
  20. color: aqua;
  21. }
  22. </style>

Main.js

  1. import Vue from 'Vue'
  2. import App from './vue/App.vue'
  3. new Vue({
  4. el: '#app',
  5. template: '<App/>',
  6. components: {
  7. App
  8. }
  9. })

打包vue檔案

npm安裝vue-loader

  1. npm install vue-loader@14.2.2 vue-template-compiler --save-dev

webpack.config.js配置檔案

  1. {
  2. test: /\.vue$/,
  3. use: ['vue-loader']
  4. }

plugin外掛

  • plugin是什麼?

    • plugin是外掛的意思,通常是用於對某個現有的架構進行擴充套件。
    • webpack中的外掛,就是對webpack現有功能的各種擴充套件,比如打包優化,檔案壓縮等等。
  • loader和plugin區別
    • loader主要用於轉換某些型別的模組,它是一個轉換器。
    • plugin是外掛,它是對webpack本身的擴充套件,是-個擴充套件器。
  • plugin的使用過程:
    • 步驟一: 通過npm安裝需要使用的plugins(某些webpack已經內建的外掛不需要安裝)
    • 步驟二:在webpack.config.js中的plugins中配置外掛。
  • 下面,我們就來看看可以通過哪些外掛對現有的webpack打包過程進行擴容,讓我們的webpack變得更加好用。
  1. const webpack = require('webpack')
  2. plugins: [
  3. new webpack.BannerPlugin('最終版權歸洛依塵所有')
  4. ],

打包html的plugin

  • 目前,我們的index.html檔案是存放在專案的根目錄下的。

    • 我們知道,在真實發布專案時 ,釋出的是dist資料夾中的內容,但是dist資料夾中如果沒有index.html檔案,那麼打包的js等檔案也就沒有意義了。
    • 所以,我們需要將index.html|檔案打包到dist資料夾中,這個時候就可以使用HtmlWebpackPlugin外掛
  • HtmlWebpackPlugin外掛可以為我們做這些事情:

    • 自動生成一個index.html檔案(可以指定模板來生成)
    • 將打包的js檔案,自動通過script標籤插入到body中
  • 安裝HtmlWebpackPlugin外掛

    1. npm install html-webpack-plugin@3.2.0 --save--dev
  • 使用外掛,修改webpack.config.js檔案中plugins部分的內容如下:

    • 這裡的template表示根據什麼模板來生成index.html
    • 另外,我們需要刪除之前在output中新增的publicPath屬性
    • 否則插入的script標籤中的src可能會有問題
    1. plugins: [
    2. new webpack.BannerPlugin('最終版權歸洛依塵所有'),
    3. new HtmlWebpackPlugin({
    4. template:'index.html'
    5. // 根據index.html模板生成
    6. })
    7. ],

js壓縮的Plugin

  • 在專案釋出之前,我們必然需要對js等檔案進行壓縮處理

    • 這裡,我們就對打包的js檔案進行壓縮
    • 我們使用一個第三方的外掛uglifyjs-webpack-plugin ,並且版本號指定1.1.1 ,和CL2保持-致
    1. npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
  • 修改webpack.config.js檔案,使用外掛:

    1. plugins: [
    2. new webpack.BannerPlugin('最終版權歸洛依塵所有'),
    3. new HtmlWebpackPlugin({
    4. template:'index.html'
    5. // 根據index.html模板生成
    6. }),
    7. new UglifyjsWebpackPlugin()
    8. ],

搭建本地伺服器

  • webpack提供了一個可選的本地開發伺服器,這個本地伺服器基於node.js搭建,內部使用express框架,可以實現我們想要的讓瀏覽器自動重新整理顯示我們修改後的結果。

  • 不過它是一-個單獨的模組,在webpack中使用之前需要先安裝它

    1. npm install --save-dev webpack-dev-server@2.9.1
  • devserver也是作為webpack中的一個選項,選項本身可以設定如下屬性:

    • contentBase :為哪一個資料夾提供本地服務 ,預設是根資料夾,我們這裡要填寫./dist
    • port :埠號
    • inline :頁面實時重新整理
    • historyApiFallback :在SPA頁面中,依賴HTML5的history模式
  • webpack.config.js檔案配置修改如下:

    1. devServer:{
    2. contentBase:'./dist',
    3. inline:true,
    4. }
  • 我們可以再配置另外一個scripts :

    1. "dependencies": {
    2. "html-webpack-plugin": "^3.2.0",
    3. "uglifyjs-webpack-plugin": "^1.1.1",
    4. "vue": "^2.6.14"
    5. },

    --open引數表示直接開啟瀏覽器