1. 程式人生 > 其它 >Vue全家桶--11 Webpack和Vue-Loader打包資源

Vue全家桶--11 Webpack和Vue-Loader打包資源

Vue全家桶--11 Webpack和Vue-Loader打包資源

11.1 Webpack介紹

11.1.1 Webpack是什麼

Webpack 是一個前端的靜態模組資源打包工具,能讓瀏覽器也支援模組化。它將根據模組的依賴關係進行靜態分
析,然後將這些模組按照指定的規則生成對應的靜態資源。

11.1.2 Webpack作用

**Webpack 核心主要進行 JavaScript 資源打包
**如下圖,它可以結合其他外掛工具,將多種靜態資源css、png、sass 分類轉換成一個個靜態檔案,這樣可以減
少頁面的請求。
**可整合 babel 工具實現 EcmaScript 6 轉 EcmaScript 5 ,解決相容性問題
**可整合 http 伺服器
**可整合模組熱載入,當代碼改變後自動重新整理瀏覽器 等等功能

11.1.3 參考資料

webpack1 和 webpack2+ 版本變化很大,基本上推倒重來, webpack1 目前已經基本不用了。

**webpack1 官網 https://webpack.github.io/
**webpack2.x 英文官網 https://webpack.js.org/
**webpack2.x 中文官網 https://webpack.docschina.org/
**webpack2.x 指南文件:https://webpack.docschina.org/guides/

11.2 Webpack安裝和案例

11.2.1 全域性安裝

1. 安裝 webpack

安裝最新版本
npm install 
--global webpack 或者 安裝特定版本 npm install --global webpack@<version>

2. 如果上面安裝的是 webpack v4+ 版本, 還需要安裝 CLI , 才能使用 webpack 命令列

npm install --1 global webpack-cli

npm install --1 global webpack-cli

3. 如果安裝後,命令列視窗 webpack 命令不可用,則手動配置 全域性目錄的 環境變數

11.2.2 快速入門

VSCode 中安裝外掛 Node Snippets ,有程式碼快捷提示

(1)打包JS模組

1.1 全域性安裝 [email protected][email protected]

npm i -g [email protected]
npm i -g [email protected]

1.2 安裝後檢視版本號。如果有紅色字提醒,沒關係忽略它

webpack -v

1.3 如果安裝後,命令列視窗 webpack 命令不可用,則配置環境變數

參考網址:https://www.cnblogs.com/steamed-twisted-roll/p/11299429.html

1.4 建立以下目錄結構和檔案

webpack-demo1
|— index.html
|— js
    |- bar.js
    |— main.js

1.5bar.js

// node 模組化程式設計, 匯出函式
module.exports = function () {
console.log('我是 bar 模組')
}

1.6main.js

var bar = require('./bar') // 可省略 .js 字尾名
bar() // 呼叫 bar.js 中的函式

1.7 node 執行 js 模組,注意命令執行所在目錄: WebStudy\webpack-demo1

1.8. index.html 檔案引入 main.js , 如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script src="./js/main.js"></script>
</body>
</html>

1.9 訪問index.html,瀏覽器無法識別JS模組化檔案

**Node 執行是可以的

1.10 打包 JS,注意命令執行所在目錄: WebStudy\webpack-demo1 ,不要少了 -o
命令: webpack 模組入口檔案路徑 -o 模組出口檔案路徑

1.11將 index.html 引入的 JS 檔案改為打包之後,瀏覽器可以識別的 JS目標檔案

<body>
    <script src="./js/bundle.js"></script>
</body>

1.12 輸出正常

(2)改造目錄結構

(3)打包配置檔案webpack.config.js

// 引用 Node.js 中的 path 模組,處理檔案路徑的小工具
const path = require("path");
// 1. 匯出一個webpack具有特殊屬性配置的物件
module.exports = {
    // 指定模式配置,取值: none(什麼也沒有), development or production(預設的)
    // 如, production 模式打包後 bundle.js是壓縮版本的, development則不是壓縮的
    mode:'none',
    // 入口
    entry: './src/main.js', // 入口模組檔案路徑
    // 出口是物件
    output: {
        // path 必須是一個絕對路徑 , __dirname 是當前js的絕對路徑:
        //D: \StudentProject\WebStudy\webpack- demo2
        path: path.join(__dirname, './dist/'), // 打包的結果檔案儲存目錄
        filename: 'bundle.js' // 打包的結果檔名
    }
}

11.2.3總結全域性安裝

不推薦 全域性安裝 webpack。全域性安裝的 webpack ,在打包專案的時候,使用的是你安裝在自己電腦上的
webpack,如果專案到了另一個人的電腦上,他可能安裝的是舊版本 webpack。那麼就可能涉及相容性的問題。而
且如果他沒有在全域性安裝 webpack 則就無法打包。

所以,為了解決以上的問題,官方推薦本地安裝 webpack,就是將 webpack 安裝到對應專案中。這樣專案到哪裡,
webpack 就跟到哪裡(webpack 打包工具隨著專案走)。

11.2.4 本地安裝(推薦)

本地安裝的時候,建議把 webpack 安裝到 devDependencies 開發依賴 ( --save-dev ) 中,因為 webpack 只是一個打包工具,專案如果需要上線,上線的是打包的結果,而不是這個工具。

所以我們為了區分生產環境和開發環境依賴,通過 --save (生產環境)和 --save-dev (開發環境)來區分。

本地安裝命令

安裝最新版本
npm install --save-dev webpack
安裝特定版本
npm install --save-dev webpack@<version>

Demo:

a.先把全域性安裝的 webpack 和 webpack-cli 解除安裝掉

npm uninstall -g webpack
npm uninstall -g webpack-cli

b.安裝 [email protected] 與 webpack-cli

# 1. 進入到 webpack-demo3
cd d:\StudentProject\WebStudy\webpack-demo3
# 2. 初始化專案 `-y` 是採用預設配置
npm init -y
# 3. 安裝 v4.35.2 ,不要少了 v
npm i -D [email protected]
# 安裝 CLI
npm i -D [email protected]

c.在本地安裝的 webpack ,要通過在專案資料夾下 package.json 檔案中的 scripts 配置命令對映

"scripts": {
"show": "webpack -v",
"start": "node ./src/main.js""build": "webpack"
},

d.然後再通過 npm run 命令別名 執行對應命令

npm run show
npm run build 
npm run start
npm start

11.3 EcmaScript 6 模組規範

匯出模組 export (等價於 module.exports)

匯入模組 import (等價於 require)

ES6參考文件:https://es6.ruanyifeng.com/

11.3.1 匯出預設成員

語法:預設成員只能有一個,不然會報錯

export default 成員
// 匯出函式
/* module.exports = function () {
console.log('我是 bar 模組---Node')
} */
// ES6 , 匯出一個預設成員(任意型別),一個js中只能有一個 default。可以預設匯出任意型別成員
/* export default function (){
console.log('我是 bar 模組---ES6')
} */
// export default 'hello'
export default {
    name: 'mxg'
}

11.3.2 匯入預設成員

import xxx from 模組檔案
// Node 匯入模組
// var bar = require('./bar')
// bar()
// ES6 匯入
// 預設載入的是 export default 成員
import bar from './bar'
// bar()
// console.log( bar )

11.3.3 匯出非預設成員

語法:非預設成員必須要有成員名稱

export 成員
export const x = 'xxx';
export const y = 'yyy';
export function add(a, b) {
    return (a - 0) + (b - 0);
}

錯誤提示:

//沒有變數名,錯誤的
export 'xxx'
// 沒有函式名,錯誤的
export function (a, b) {
return a + b
}

11.3.4 匯入非預設成員

// 方式一:按需匯入指定成員,採用 解構賦值 的方式
import {成員名1, 成員名2, ..., 成員名n} from 模組檔案
// 方式二:一次匯入模組檔案中的所有成員(包含 default 成員)
import * as 別名 from 模組檔案
// 通過 export xxx 匯出的非預設成員,可使用 解構賦值 的方式按需載入成員
// x 對應就是 bar.js 中的 x 成員,y 對應就是 bar.js 中的 y 成員,
import {x, y, add} from './bar'
console.log(x, y, add(10, 20))
// 一次性載入 export xxx 匯出所有成員, 不採用解構賦值
import * as bar2 from './bar'
console.log(bar2)

11.4 打包 CSS/Images等資源

11.4.1 打包CSS資源

(1)安裝 style-loader 和 css-loader 依賴

  css-loader 是 將 css 裝載到 javascript;
  style-loader 是讓 javascript 認識 css。

npm install --save-dev style-loader css-loader

(2)修改 webpack.config.js 檔案

// 引用 Node.js 中的 path 模組,處理檔案路徑的小工具
const path = require("path");
// 1. 匯出一個webpack具有特殊屬性配置的物件
module.exports = {
    // 指定模式配置,取值: none(什麼也沒有), development or production(預設的)
    // 如, production 模式打包後 bundle.js是壓縮版本的, development則不是壓縮的
    mode: 'none',
    // 入口
    entry: './src/main.js', // 入口模組檔案路徑
    // 出口是物件
    output: {
        // path 必須是一個絕對路徑 , __dirname 是當前js的絕對路徑:
        //D: \StudentProject\WebStudy\webpack- demo2
        path: path.join(__dirname, './dist/'), // 打包的結果檔案儲存目錄
        filename: 'bundle.js' // 打包的結果檔名
    },
    module: { // 模組
        rules: [ // 規則
            {
                test: /\.css$/, // 正則表示式,匹配 .css 檔案資源
                use: [ // 使用的 Loader ,注意順序不能錯
                    'style-loader',
                    'css-loader'
                ]
            }
        ]
    }
}

(3)在src資料夾建立 css 資料夾, css資料夾下建立 style.css

body {
    background-color: cadetblue;
}

(4)在 main.js 只引入 style.css

import './css/style.css'

(5)重新打包編譯,index.html顯示上述效果!

npm run build

****原理:

F12檢視 index.html 原始碼後,其實是將 CSS 檔案內容轉成一個 JavaScript 模組,然後在執行 JavaScript 時,會將樣式動態使用 <sytle> 標籤作用在頁面<head> 標籤下

11.4.2 打包Images資源

(1)安裝 file-loader 依賴

npm install --save-dev file-loader

(2)修改 webpack.config.js

// 引用 Node.js 中的 path 模組,處理檔案路徑的小工具
const path = require("path");
// 1. 匯出一個webpack具有特殊屬性配置的物件
module.exports = {
    // 指定模式配置,取值: none(什麼也沒有), development or production(預設的)
    // 如, production 模式打包後 bundle.js是壓縮版本的, development則不是壓縮的
    mode: 'none',
    // 入口
    entry: './src/main.js', // 入口模組檔案路徑
    // 出口是物件
    output: {
        // path 必須是一個絕對路徑 , __dirname 是當前js的絕對路徑:
        //D: \StudentProject\WebStudy\webpack- demo2
        path: path.join(__dirname, './dist/'), // 打包的結果檔案儲存目錄
        filename: 'bundle.js' // 打包的結果檔名
    },
    module: { // 模組
        rules: [ // 規則
            {
                test: /\.css$/, // 正則表示式,匹配 .css 檔案資源
                use: [ // 使用的 Loader ,注意順序不能錯
                    'style-loader',
                    'css-loader'
                ]
            }, {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
                    'file-loader'
                ]
            }
        ]
    }
}

(3) 打包編譯

注意點:

如果直接訪問根目錄下的 index.html ,那麼圖片資源路徑就無法訪問到。
解決方案:就是把 index.html 放到 dist 目錄中。
但是 dist 是打包編譯的結果,而非原始碼,所以把 index.html 放到 dist 就不合適。
而且如果我們一旦把打包的結果檔名 bundle.js 改了之後,則 index.html 也要手動修改。
綜合以上遇到的問題,可以使用一個外掛: html-webpack-plugin 來解決

11.4.3html-webpack-plugin

安裝外掛

npm install --save-dev html-webpack-plugin

修改webpack.config.js

// 引用 Node.js 中的 path 模組,處理檔案路徑的小工具
const path = require("path");

// 引入外掛
const HtmlWebpackPlugin = require('html-webpack-plugin');

// 1. 匯出一個webpack具有特殊屬性配置的物件
module.exports = {
    // 指定模式配置,取值: none(什麼也沒有), development or production(預設的)
    // 如, production 模式打包後 bundle.js是壓縮版本的, development則不是壓縮的
    mode: 'none',
    // 入口
    entry: './src/main.js', // 入口模組檔案路徑
    // 出口是物件
    output: {
        // path 必須是一個絕對路徑 , __dirname 是當前js的絕對路徑:
        //D: \StudentProject\WebStudy\webpack- demo2
        path: path.join(__dirname, './dist/'), // 打包的結果檔案儲存目錄
        filename: 'bundle.js' // 打包的結果檔名
    },
    module: { // 模組
        rules: [ // 規則
            {
                test: /\.css$/, // 正則表示式,匹配 .css 檔案資源
                use: [ // 使用的 Loader ,注意順序不能錯
                    'style-loader',
                    'css-loader'
                ]
            }, {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
                    'file-loader'
                ]
            }
        ]
    },
    // 配置外掛
    plugins: [
        new HtmlWebpackPlugin({
            // 此外掛作用是將 index.html 打包到 bundle.js 所在目錄中,
            // 同時也會在 index.html 中自動的 <script> 引入 bundle.js
            // 注意:其中的檔名 bundle 取決於上面output.filename中指定的名稱
            template: './index.html'
        })
    ]
}

打包編譯,dist資料夾中就有了index.html,訪問正常!

11.5 實時重新載入

11.5.1 說明

採用 webpack 提供的工具: webpack-dev-server ,它允許在執行時更新所有型別的模組後,而無需手動打
包和重新整理頁面,會自動打包和重新整理頁面。可以很大程度提高開發效率。

參考:https://webpack.docschina.org/guides/development/#使用-webpack-dev-server

11.5.2 實操

安裝依賴

npm install --save-dev webpack-dev-server

修改 webpack.config.js 配置

// 引用 Node.js 中的 path 模組,處理檔案路徑的小工具
const path = require("path");
// 引入外掛
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 1. 匯出一個webpack具有特殊屬性配置的物件
module.exports = {
    // 指定模式配置,取值: none(什麼也沒有), development or production(預設的)
    // 如, production 模式打包後 bundle.js是壓縮版本的, development則不是壓縮的
    mode: 'none',
    // 入口
    entry: './src/main.js', // 入口模組檔案路徑
    // 出口是物件
    output: {
        // path 必須是一個絕對路徑 , __dirname 是當前js的絕對路徑:
        //D: \StudentProject\WebStudy\webpack- demo2
        path: path.join(__dirname, './dist/'), // 打包的結果檔案儲存目錄
        filename: 'bundle.js' // 打包的結果檔名
    },
    module: { // 模組
        rules: [ // 規則
            {
                test: /\.css$/, // 正則表示式,匹配 .css 檔案資源
                use: [ // 使用的 Loader ,注意順序不能錯
                    'style-loader',
                    'css-loader'
                ]
            }, {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
                    'file-loader'
                ]
            }
        ]
    },
    // 配置外掛
    plugins: [
        new HtmlWebpackPlugin({
            // 此外掛作用是將 index.html 打包到 bundle.js 所在目錄中,
            // 同時也會在 index.html 中自動的 <script> 引入 bundle.js
            // 注意:其中的檔名 bundle 取決於上面output.filename中指定的名稱
            template: './index.html'
        })
    ],
    // 實時重新載入
    devServer: {
        contentBase: './dist'//配置打包的目標路徑
    }
}

修改package.json的scripts   --open 選項打包成功,自動開啟瀏覽器

"dev": "webpack-dev-server --open"

然後npm run dev 執行,就可以了

11.6 Babel瀏覽器相容性

11.6.1 安裝 Bable

npm install -D babel-loader @babel/core  @babel/preset-env

11.6.2 配置 webpack.config.js

// 引用 Node.js 中的 path 模組,處理檔案路徑的小工具
const path = require("path");

// 引入外掛
const HtmlWebpackPlugin = require('html-webpack-plugin');

// 1. 匯出一個webpack具有特殊屬性配置的物件
module.exports = {
    // 指定模式配置,取值: none(什麼也沒有), development or production(預設的)
    // 如, production 模式打包後 bundle.js是壓縮版本的, development則不是壓縮的
    mode: 'none',
    // 入口
    entry: './src/main.js', // 入口模組檔案路徑
    // 出口是物件
    output: {
        // path 必須是一個絕對路徑 , __dirname 是當前js的絕對路徑:
        //D: \StudentProject\WebStudy\webpack- demo2
        path: path.join(__dirname, './dist/'), // 打包的結果檔案儲存目錄
        filename: 'bundle.js' // 打包的結果檔名
    },
    module: { // 模組
        rules: [ // 規則
            {
                test: /\.css$/, // 正則表示式,匹配 .css 檔案資源
                use: [ // 使用的 Loader ,注意順序不能錯
                    'style-loader',
                    'css-loader'
                ]
            }, {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
                    'file-loader'
                ]
            }, {
                test: /\.m?js$/,
                exclude: /(node_modules|bower_components)/, // 排除的目錄
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'] // 內建好的轉譯工具
                    }
                }
            }
        ]
    },
    // 配置外掛
    plugins: [
        new HtmlWebpackPlugin({
            // 此外掛作用是將 index.html 打包到 bundle.js 所在目錄中,
            // 同時也會在 index.html 中自動的 <script> 引入 bundle.js
            // 注意:其中的檔名 bundle 取決於上面output.filename中指定的名稱
            template: './index.html'
        })
    ],
    // 實時重新載入
    devServer: {
        contentBase: './dist'//配置打包的目標路徑
    }
}

11.7 Vue-Loader打包Vue單檔案元件

11.7.1 打包Vue基本配置

安裝 vue-loader 和 vue-template-compiler 依賴

npm install -D vue-loader vue-template-compiler

修改 webpack.config.js 配置

1.宣告外掛

const VueLoaderPlugin = require('vue-loader/lib/plugin');

2.模組規則,配置vue-loader

{
                test: /\.vue$/,
                loader:'vue-loader'
            }

3. 配置外掛

new VueLoaderPlugin()
// 引用 Node.js 中的 path 模組,處理檔案路徑的小工具
const path = require("path");

// 引入外掛
const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');

// 1. 匯出一個webpack具有特殊屬性配置的物件
module.exports = {
    // 指定模式配置,取值: none(什麼也沒有), development or production(預設的)
    // 如, production 模式打包後 bundle.js是壓縮版本的, development則不是壓縮的
    mode: 'none',
    // 入口
    entry: './src/main.js', // 入口模組檔案路徑
    // 出口是物件
    output: {
        // path 必須是一個絕對路徑 , __dirname 是當前js的絕對路徑:
        //D: \StudentProject\WebStudy\webpack- demo2
        path: path.join(__dirname, './dist/'), // 打包的結果檔案儲存目錄
        filename: 'bundle.js' // 打包的結果檔名
    },
    module: { // 模組
        rules: [ // 規則
            {
                test: /\.css$/, // 正則表示式,匹配 .css 檔案資源
                use: [ // 使用的 Loader ,注意順序不能錯
                    'style-loader',
                    'css-loader'
                ]
            }, {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
                    'file-loader'
                ]
            }, {
                test: /\.m?js$/,
                exclude: /(node_modules|bower_components)/, // 排除的目錄
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'] // 內建好的轉譯工具
                    }
                }
            },{
                test: /\.vue$/,
                loader:'vue-loader'
            }
        ]
    },
    // 配置外掛
    plugins: [
        new HtmlWebpackPlugin({
            // 此外掛作用是將 index.html 打包到 bundle.js 所在目錄中,
            // 同時也會在 index.html 中自動的 <script> 引入 bundle.js
            // 注意:其中的檔名 bundle 取決於上面output.filename中指定的名稱
            template: './index.html'
        }),
        new VueLoaderPlugin()
    ],
    // 實時重新載入
    devServer: {
        contentBase: './dist'//配置打包的目標路徑
    }
}

11.7.2 webpack與Vue單檔案元件案例

目錄結構

安裝vue模組

npm i vue

index.html 單頁面入口

<!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>
</head>
<body>
    <!-- 1. vue入口  -->
    <div id="app"></div>
</body>
</html>

App.vue 根元件

<template>
    <div>
        <h1>App 根元件</h1>
        <h2>{{ msg }}</h2>
        <!-- <Foo/>  -->
        <foo></foo>
        <bar></bar>
    </div>
</template>

<script>
    // 要使用某個元件,要先匯入再使用
    import Foo from  './components/Foo.vue'
    import Bar from './components/Bar.vue'

    // 匯出一個預設的成員物件 ,它就是當前元件物件 , 可以直接在物件 中使用Vue中的選項,如data/methods/watch
    export default {
        data () {
           return {
                msg : 'hello mxg'
           }
        },
        // template: 此選項不用寫,因為上面template標籤代表的就是當前的元件模板
        // 引用子元件
        components: {
            Foo,
            Bar
        }
    }

</script>
<style scoped>
/* scoped 作用是將樣式只作用到當前元件中,不然會傳遞到其他 父子元件中 */
    h1 {
        color: red
    }
</style>

main.js打包入口檔案

import Vue from 'vue'
import App from './App.vue'

new Vue({
    el: '#app',
    template: '<App />',
    components: {App}
})

打包構建

npm run build

11.7.3 解決警告問題

// 通過這種方式引入的 vue模組,對應的是不是完整版(編譯功能,執行功能)
// 它預設引入的 vue模組中的package.json中main選項中引入的那個"main": "dist/vue.runtime.common.js"
// 而這個預設引入的是執行版,沒有編譯功能,所以會發出警告
// import Vue from 'vue' 
// 解決:手動的引入指定的版本,正面引入的是完整版
// import Vue from 'vue/dist/vue.js'
// 方式2 :採用webpack配置完整版vue.js
import Vue from 'vue'
import App from './App.vue'
/* 
new Vue({
    el: '#app',
    // template 實質上沒有編譯和渲染功能,而當前編譯功能可以直接採用 vue-loader進行編譯,
    // 而渲染功能實質上是通過render函式 來進行渲染元件,所以只需要在此處指定 render渲染元件即可 
    // template: '<App />', // <App></App>
    // render: function (h) { // h它是一個函式,這個函式用於要接收渲染的元件
    //     return h(App) //函式的返回值就是渲染的結果
    // },
    // 如果採用render進行渲染,則 main.js 當中的 components可以省略
    // components: {App}
    // 箭頭函式 簡寫1
    // render: h => {
    //    return h(App)
    // }
    // 箭頭函式 簡寫2
    render: h => h(App)

}) */
new Vue({
    render: h => h(App)
}).$mount('#app')

11.7.4 .vue單檔案元件完整版

App.vue

<template>
    <div>
        <h1>App 根元件</h1>
        <h2>{{ msg }}</h2>
        <!-- <Foo/>  -->
        <foo></foo>
        <bar></bar>
    </div>
</template>

<script>
    // 要使用某個元件,要先匯入再使用
    import Foo from  './components/Foo.vue'
    import Bar from './components/Bar.vue'

    // 匯出一個預設的成員物件 ,它就是當前元件物件 , 可以直接在物件 中使用Vue中的選項,如data/methods/watch
    export default {
        data () {
           return {
                msg : 'hello mxg'
           }
        },
        // template: 此選項不用寫,因為上面template標籤代表的就是當前的元件模板
        // 引用子元件
        components: {
            Foo,
            Bar
        }
    }

</script>
<style scoped>
/* scoped 作用是將樣式只作用到當前元件中,不然會傳遞到其他 父子元件中 */
    h1 {
        color: red
    }
</style>

Foo.vue

<template>
<!-- 一個vue檔案中有且僅有一個template -->
    <div>
        <h1>我是 Foo 子元件1111</h1>
        <h2>我是 Foo子元件 h22222</h2>
    </div>
</template>
<script>
// 如果 不寫js程式碼,可以不需要 <script>
// 一般採用的是匯出一個預設成員 物件
export default {
    
}
</script>

<style scoped>
/* 如果 不寫樣式程式碼,可以不需要 <style> */
/* scoped 作用是將樣式只作用到當前元件中,不然會傳遞到其他 父子元件中 */
    h2 {
        color: blue
    }
</style>

11.7.5 模組熱替換(HMR)

// 引入node中的path模組,處理檔案路徑 的小工具
const path = require('path')
// 引入外掛
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 1. 引入 vue-loader外掛
const VueLoaderPlugin = require('vue-loader/lib/plugin')

// 1. 匯入webapck, 熱模組載入
const webpack = require('webpack')

// 匯出一個webpack具有特殊屬性配置的物件
module.exports = {
    mode: 'none', // 指定模式配置:"development" | "production" | "none"
    // 入口
    entry: './src/main.js', // 入口模組檔案路徑 
    // 出口
    output: {
        // path: './dist/', 錯誤的,要指定絕對路徑
        path: path.join(__dirname, './dist/'), //打包的結果檔案生成的目錄要是絕對路徑
        filename: 'bundle.js'
    },

    // 配置外掛
    plugins: [  
        new HtmlWebpackPlugin({
            // 指定要打包的模板頁面
            // 就會將 index.html 打包到與 bundle.js 所在同一目錄下面,
            // 同時在 index.html 中會自動的使用script 標籤引入bundle.js
            template: './index.html'
        }),
        // 3. 請確保引入這個外掛!
        new VueLoaderPlugin(),
        // 3. 配置熱模組載入物件
        new webpack.HotModuleReplacementPlugin()
    ],
    // 實時重新載入
    devServer: {
        // 目標路徑
        contentBase: './dist',
        // 2. 開啟熱模組載入,
        hot: true 
    },
    module: {
        rules: [ //配置轉換規則
            {
                test: /\.css$/, // 注意,不要有單引號,正則表達 式,匹配 .css 檔案資源 
                use: [
                    // 根據外國人的習慣來的順序,而且順序不要寫錯
                    'style-loader', // js識別css
                    'css-loader' // css 轉換為 js
                ]
            },
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
                    'file-loader'
                ]
            },
            // 解決相容性問題
            {
                test: /\.m?js$/,
                exclude: /(node_modules)/, // 排除的目錄
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'] // babel中內容的轉換規則工具
                    }
                }
            },
            // 2. 處理 .vue 單檔案元件
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            }
        ]
    },

    // 解析完整版 vue.js
    // resolve: { 
    //     alias: {
    //         'vue$': 'vue/dist/vue.js'
    //     }
    // }


}
You are never too old to set another goal or to dream a new dream!!!