Day16-Vue CLI 环境设定与打包部属

package.json专案与套件相依设定档

在开启专案时我们使用的npm run serve指令就是在package.json中被定义的,打开package.json可以看到以下内容

"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  }

其中的vue-cli-service可以在./node_modules/.bin/中找到,在这个档案中可以省略这段路径。

build打包专案

专案完成时可以在终端机下build指令,把.vue档案转译成浏览器读的.js档案

npm run build

完成後就会发现资料夹多了一个dist资料夹

DONE  Compiled successfully in 39372ms 下午6:35:57

  File                                 Size                                    Gzipped

  dist\js\chunk-vendors.cfd96c1f.js    86.10 KiB                               32.23 KiB
  dist\js\app.30e28c5b.js              4.63 KiB                                1.65 KiB
  dist\css\app.f945facf.css            0.36 KiB                                0.24 KiB

  Images and other types of assets omitted.

 DONE  Build complete. The dist directory is ready to be deployed.
 INFO  Check out deployment instructions at https://cli.vuejs.org/guide/deployment.html

被打包的档案名称後面都有加上杂凑值,就像是app.30e28c5b.js

相依套件版本

在以下这个区域中可以看到专案中所使用的套件,有了这个设定的地方,在团队版本控制上就方便许多。

  • dependencies: 打包build时一起包装进去,并发布到线上环境
  • devDependencies: 仅於开发阶段,不会被打包
  • ~符号 : 找目前最小版本号安装
  • ^符号 : 找最新的中版本号安装
"dependencies": {
    "core-js": "^3.6.5",
    "vue": "^3.0.0"
  },
"devDependencies": {
  "@vue/cli-plugin-babel": "~4.5.0",
  "@vue/cli-plugin-eslint": "~4.5.0",
  "@vue/cli-service": "~4.5.0",
  "@vue/compiler-sfc": "^3.0.0",
  "babel-eslint": "^10.1.0",
  "eslint": "^6.7.2",
  "eslint-plugin-vue": "^7.0.0"
}

vue.config.js设定档

需要调整webpack参数时可以建立vue.config.js档案,位置就和package.json同一层。

在build时希望不要有杂凑值就可以在此档案写以下内容

module.exports = {
    filenameHashing: false,
}

开发时的跨网域存取proxy-devServer

开发专案的时候可能会遇到远端呼叫API跨域限制,proxy-devServer就派上用场了!

和书中一样用uBike资料作范例(https://data.ntpc.gov.tw/api/datasets/71CD1490-A2DF-4198-BEF1-318479775E8A/json/preview)

在元件中使用fetch取得远端资料,因为网域不同的限制,会显示错误讯息

mounted() {
    fetch("https://data.ntpc.gov.twapi/datasets/71CD1490-A2DF-4198-BEF1-318479775E8A/json/preview")
      .then((res) => res.json())
      .then((text) => console.log(text));
  },

Untitled

解决方法就是在vue.config.js设定proxy

module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: 'https://data.ntpc.gov.tw/api/',  //远端路径
								pathRewrite: { '^/api': '' },
                changeOrigin: true,
                ws: true
            },
        }
    }
}

指定好路径之後就可以将fetch中的路径改为相对路径,如此一来就可以抓到远端的资料了

mounted() {
    fetch("api/datasets/71CD1490-A2DF-4198-BEF1-318479775E8A/json/preview")
      .then((res) => res.json())
      .then((text) => console.log(text));
},

多页式应用(MPA)入口设定

上述的范例都是单页式(SPA)为主,那多页式(MPA)呢? 多页式也就代表着多个进入点,此时就要把原先的入口做点变化

  1. src/之下建立一个pages资料夹,新增list.htmlproduct.html档案,并在src/中新增list.jsproduct.js
  2. list.jsproduct.js的内容和main.js差不多,mounted的目标可自行更动
import { createApp } from 'vue';
import App from './App.vue';

createApp(App).mount('#list-app')
  1. list.html放入对应的节点
<div id="list-app">list</div>
  1. 接着修改vue.config.js
module.exports = {
    pages: {
        list:
        {
            entry: `./src/list.js`,  //页面入口,启动Vue.createApp的档案位置
            template: `./src/pages/list.html`,  //网页所在路径
            filename: `/list.html` //build时存放的位置
        },
        product:
        {
            entry: `./src/product.js`,
            template: `./src/pages/product.html`,
            filename: `/product.html`
        }
    }
}
  1. 最後一步复制src/list.htmlproduct.htmlpublic/之下
  2. 执行build就可以从http://localhost:8081/list.html看到画面

补充:

不想一页页设定的话可以用以下方式

//书中所提供

const path = require('path');
const glob = require('glob');
const resolve = dir => path.join(__dirname, dir);
const getPagesEntry = () => {
    const entry = {};

    // 搜寻专案内 /src/pages/ 所有的 HTML 档案 
    const fileNameArr = glob
        .sync(path.join(__dirname, './src/pages/**/*.html'))
        .map(p => p.split('/src/pages/')[1])
        .map(p => p.replace('.html', ''));

    // 建立 pages 物件内容,存放到 entry 物件内 
    fileNameArr.forEach(e => {
        entry[e] = {
            entry: `./src/${e}.js`,
            template: `./src/pages/${e}.html`,
            filename: `${e}.html`,
        };
    });

    return entry;
};
// 最後将 getPagesEntry() 的结果回传给 page // 就可以取得所有档案的路径了 
module.exports = {
    pages: getPagesEntry()
}

整合第三方函式库

Vue中想加入第三方函式库时可以透过npm安装(例如jQuery)

npm install jquery

完成後就可以看到package.json多了jquery

"dependencies": {
    "core-js": "^3.6.5",
    "jquery": "^3.6.0",
    "vue": "^3.0.0"
 },

在App.vue中引入

<script>
import HelloWorld from "./components/HelloWorld.vue";
import $ from "jquery";

export default {
  name: "App",
  components: {
    HelloWorld,
  },
  mounted() {
    console.log($("img").attr("src"));
  },
};
</script>

builddependencies中的jQuery也会被打包进去,让档案变很大

File                                 Size                                      Gzipped  

  dist\js\chunk-vendors.63013dfb.js    174.62 KiB                                62.29 KiB
  dist\js\app.fa51fa3c.js              4.70 KiB                                  1.69 KiB
  dist\css\app.39958ea0.css            0.36 KiB                                  0.24 KiB

可以改用外部引入让档案大小减少

改用cdn方式在public/index.html中放入

<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

另外在vue.config.js加入externals设定

module.exports = {
    configureWebpack: {
        externals: { 'jquery': '$' }
    }
}

这样就大幅的缩减档案大小了

File                                 Size                             Gzipped

  dist\js\chunk-vendors.cfd96c1f.js    86.10 KiB                      32.23 KiB
  dist\js\app.e9b913ec.js              4.73 KiB                       1.70 KiB
  dist\css\app.39958ea0.css            0.36 KiB                       0.24 KiB

CLI章节到此结束,其实看完书後大概懂了一点概念,笔记的过程中边跟着书中做,可是好几次出现错误卡了好久,不知道什麽时候用npm run serve还是npm run build,现在可能也是半懂,之後实际做案子应该会有更深入的了解吧!! 另外,vue.config.js这部分感觉还有很多设定,有时间的话也想在深入研究一下,今天就到这边拉~


<<:  Day16-旧网站重写成Vue_7_点击滚动

>>:  [Day18] - Django-REST-Framework API 呼叫及介面操作

Day03_神说要有光~资安三要素V.S.资产盘点 XD"(我会不会因为乱下标题被打)

今天在思考。。。我要乖乖照着上课的笔记打吗?想想,我还是随我自已的意思讲好了,啊呜~ 来人~请播放『...

C# 一些基础特性

C# 类别 class 定义的类型是参考型别, 在运行时当你声明一个参考类别变数, 此变数会包含 n...

Ubersuggest 免费 SEO 工具教学,支援中文关键字分析与内容建议

经营自媒体网站最重要的就是要让文章被看见,有了流量才有信服力,而要曝光文章最快的方法除了购买付费广告...

[Day 05] Swift 简单入门

由於目前只是想做一个跨 Android手机以及 iOS手机的 APP,所以目前是想先用之前 稍微摸过...

【第二十四天 - XSS Lab(2)-2】

接续昨天的 XSS Lab(2)-1,今天继续解 https://alf.nu/alert1 Tem...