iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 12
0
Modern Web

Angular 深入淺出三十天系列 第 12

[Angular 深入淺出三十天] Day 11 - Angular CLI 常用指令說明(二)

「哇賽,這 Angular CLI 還真不是普通地強大耶!!既然它這麼強大,一定還有其他好用的功能吧?!之前每次開新專案之後,Coding 前要用的 ng serve 呢?」Wayne 想起之前用的指令後問道。

「當然還有很多好用的功能阿!我跟你說,關於這個 ng serve 阿...」


ng serve

以前在開發前端網頁的時候,除了直接將 HTML 檔拖曳到瀏覽器視窗裡看之外,大概就是用類似 WAMP、XAMP、MAMP 之類的工具來啟動 Web-Server,讓我們可以透過在瀏覽器的網址列輸入 localhost 來看到放在指定資料夾中的網頁。

但就算如此,我們還是凡是有改任何的程式讓瀏覽器重新刷新,才能看到我們更改過後的程式碼。雖然不是什麼很難的事情,但還是必須花費不少時間在程式碼與瀏覽器之間來回切換。

而後在 NodeJS 普及之下,出現了像是 GulpGrunt 的自動化流程工具,讓我們在開發的時候,可以更即時且方便地看到結果;以及隨著前端技術的進步與相關工具的蓬勃發展下,需要像是 BrowserifyWebpack 的預處理、打包工具來幫我們把我們原本所撰寫的程式碼,處理、包裝成瀏覽器看得懂的 js 檔、css 檔與 html 檔。

不過凡事一定都有好有壞,當工具越來越多的時候,就表示我們要會的東西就越來越多;當一個專案所使用的工具越來越多的時候,就表示後續的維護就越來越困難。為什麼呢?

假設前端工具目前就上述四套 Gulp 和 Grunt 負責處理流程;而 Browserify 與 Webpack 負責預處理及打包我們的程式碼。所以一個專案所使用的工具組可能就會分成以下四種:

  • Gulp + Browserify
  • Grunt + Webpack
  • Gulp + Webpack
  • Grunt + Browserify

有意識到恐怖的地方嗎?假設今天我們只會其中一種組合,但未來經手或維護別人的專案的時候,我可能就會碰到其他三種組合,所以我們就得都學都會!如果未來有其他更多的工具(實際上也有其他更多的工具),那光是學習這些工具所花費的時間可能都會比我們實際寫程式碼的時間還多。這對一間公司、一個團隊、甚至是個人來說,成本都太高昂了。

好在, Angular CLI 都幫我們處理好了!

謎之音:感恩 Angular!讚嘆 Angular!

當我們在開發 Angular 的應用程式時,只需在終端機中輸入:

ng serve

Angular CLI 就會幫我們處理以下這幾件事情:

  1. 啟動本地端的 Web-Server,令我們能夠在 localhost:4200 上看到我們的頁面。

  2. 將我們目前所開發的程式碼(已儲存的)編譯、打包後,讓 localhost:4200 載入

  3. 當我們儲存我們的程式碼之後,會自動重複 2. 所敘述之事項,並自動令瀏覽器重新載入,不用我們自己手動刷新。

是不是超級貼心又超級厲害?!雖然上述提到的套件也都能做到,但對不起,請自己設定。或是參考其他人的設定。

當然,ng serve 也有參數可以使用。像是:

  • --open - 當我們指令單純只下 ng serve 的時候,我們得手動開啟瀏覽器並在網址列輸入 localhost:4200 ,才能在頁面上看到我們的頁面。但加上此參數會讓 Angular CLI 在準備好之後,直接幫我們開啟頁面,不用再自己手動開啟。

  • --port - 為什麼一定要輸入 localhost:4200 才能看到頁面呢?我可以輸入 localhost:4201 或 localhost:5487 嗎?!

當然可以!之所以在 4200 才能看到頁面的關係是因為,在我們沒有使用這個參數並指定其值時,Angular CLI 幫我們啟動的 Web-Server 就只有在 port 是 4200 時才能看到頁面 (如果不知道什麼是 port 的話,可以參考維基百科的說明) ,且如果已經有應用程式已經在使用該 port 時,是不能再開啟的。

例如我們目前有了三個專案,HelloAngular、MRTStationList、MyMessageBoard。當我已經在 MRTStationList 的專案底下下過 ng serve 指令時,我就不能再在 MyMessageBoard 的專案底下下 ng serve 的指令,不然它會出現像是這樣的錯誤訊息:

Port 4200 is already in use. Use '--port' to specify a different port

表示 4200 這個 port 已經被使用了,要使用 --port 這個參數來指定使用別的 port 開啟我們的應用程式,像是: ng serve --port 5487

  • --proxy-config - 不曉得各位有沒有遇到過 CORS 的問題?一般傳統前端頁面或伺服器渲染的框架可能比較少會遇到,但在開發 Angular 這種可以前後端分離的應用程式時,過程中絕對或多或少都會遇到。這時就需要這個參數與相關設定來幫助我們解決了!通常我們會根目錄建立一個叫做 proxy.config.json 的檔案 (檔案內容之設定與原理請參考保哥的文章,我就不再贅述) ,然後將檔案的檔名指定給這個參數即可。如: ng serve --proxy-config proxy.config.json

其他更多的參數可以參考官方的 Wiki ,在此就不再多做描述。

學會了這幾個參數的用法之後,或許就有人會問:那以上這些參數可以混用嗎?!

當然可以!將參數一直加在後面就好,像是:

ng serve --port 5487 --proxy-config proxy.config.json --open

不過如此一來,可能又會覺得:每次都要打這麼長的指令好累噢!!

不怕!我教大家一個小技巧!我們將專案根目錄一個名為 package.json 的檔案打開 (不知道這個檔案是幹嘛用的朋友們,可以複習一下第四天的文章 ,然後找到 scripts 的區塊:

Imgur

接著我們將上面那一大串,取代原本在 start 裡面的值,變成像是下圖中的樣子:

Imgur

接著我們再把原本啟動時要輸入的指令,改為輸入:

npm start

這樣 NPM 就會自動幫我們執行在 start 裡的那一大串,不再需要每次都要自己打了!


上一篇
[Angular 深入淺出三十天] Day 10 - Angular CLI 常用指令說明(一)
下一篇
[Angular 深入淺出三十天] Day 12 - Angular CLI 常用指令說明(三)
系列文
Angular 深入淺出三十天33

1 則留言

0
jakeuj
iT邦新手 5 級 ‧ 2019-01-04 19:18:32

proxy 照著設定是沒cros問題

{
  "/stationnames": {
    "target": "http://tcgmetro.blob.core.windows.net",
    "secure": false
  }
}

但是還是拿不到資料

<Error>
<Code>InvalidUri</Code>
<Message>
The requested URI does not represent any resource on the server. RequestId:49cce3a6-501e-00e9-611e-a4dab4000000 Time:2019-01-04T11:11:19.4033879Z
</Message>
<UriPath>http://localhost:4200/stationnames/stations.json</UriPath>
</Error>

請問這是幾版的測試能用,剛查了一下7好像有改?
https://angular.io/guide/build#using-corporate-proxy

Leo iT邦新手 4 級‧ 2019-01-05 10:30:03 檢舉

Hi jakeuj,

一直都能用噢!

可能是在用法上有錯誤,需要更多的程式碼我才能夠幫你看是哪裡出了問題。

jakeuj iT邦新手 5 級‧ 2019-01-07 11:41:00 檢舉

要加 "changeOrigin": true

Angular 6

If you need to access a backend that is not on localhost, you will need to add the changeOrigin option as follows:

{
  "/api": {
    "target": "http://npmjs.org",
    "secure": false,
    "pathRewrite": {
      "^/api": ""
    },
    "changeOrigin": true
  }
}

Documentation below is for CLI version 6. For version 7 see here.

var HttpsProxyAgent = require('https-proxy-agent');
var proxyConfig = [{
  context: '/api',
  target: 'http://your-remote-server.com:3000',
  secure: false
}];
 
function setupForCorporateProxy(proxyConfig) {
  var proxyServer = process.env.http_proxy || process.env.HTTP_PROXY;
  if (proxyServer) {
    var agent = new HttpsProxyAgent(proxyServer);
    console.log('Using corporate proxy server: ' + proxyServer);
    proxyConfig.forEach(function(entry) {
      entry.agent = agent;
    });
  }
  return proxyConfig;
}
 
module.exports = setupForCorporateProxy(proxyConfig);
Leo iT邦新手 4 級‧ 2019-01-07 12:45:53 檢舉

/images/emoticon/emoticon12.gif

感謝 jakeuj 的分享!!

我要留言

立即登入留言