【譯】使用 Webpack 和 Poi 構建更好的 JavaScript 應用

逆葵發表於2018-07-12

譯者注:最近看到 Poi 這個也是打著零配置特點(Parcel:莫名躺槍?)的 JavaScript 打包工具,發現其在 Github 有著 3000+ Star 的同時在中文世界裡熱度卻較低,因此在 Medium 上找了一篇文章翻譯過來,方便大家瞭解之。

原文地址:blog.bitsrc.io/build-bette…

Webpack 是一個將你所有的 JavaScript 檔案,圖片、字型檔以及 CSS 等打包到一個依賴關係圖的構建工具。這使得你可以在原始碼中使用 require() 來引用本地檔案並且決定在最終的 JavaScript 包中如何處理這些本地檔案程式碼。

Poi 是一個零配置的基於 Webpack 的打包器。零配置並不是指專案完全不需要配置,而是 Poi 已經為我們配置好了大量內容。

本文將展示如何構建你的 JavaScript 應用,如何用 Webpack 進行打包以及用 Poi 進行配置。

使用 Poi 啟動一個簡單的 JavaScript 檔案

使用 Poi 部署一個 JavaScript 單檔案非常簡單。Poi 能夠啟動一個開發伺服器並且能夠在檔案發生變化時自動過載頁面。

首先,在系統中安裝 Poi。

$ npm i -g poi
複製程式碼

然後,新建一個專案目錄。

$ mkdir js-app
$ cd js-app
複製程式碼

在該目錄下新建 index.js 檔案:

document.getElementById ('app').innerHTML = `
  <h1>Hello world!</h1>
`;
複製程式碼

這裡 document.getElementById 獲取 id 名為“app”的 div,其將由 Poi 建立。在該 div 內部是一句簡單的“Hello World”。

為了在瀏覽器中啟動該檔案,開啟終端並且執行命令 poi。Poi 將處理所有 webpack 相關的東西並且在 localhost:4000 上部署該檔案。

如果你將 index.js 放置在其他資料夾,比如 src,那你需要執行命令 poi src/index.js 來在開發伺服器上啟動該檔案。

使用 Poi 定製 HTML 模板

儘管 Poi 為我們的應用提供了現成的 HTML 模板,我們仍然可以按照自己的喜歡定製它。下面將展示如何使用 Poi 定製 HTML 頁面中的 head 標籤。

在專案目錄中新建一個名為 index.ejs 的新檔案,其程式碼如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Running JavaScript Apps with POI</title>
  </head>
  <body>
    <div id="app"></app>
  </body>
</html>
複製程式碼

再次執行命令 poi 將會得到一個標題更新了的新頁面。如果你用瀏覽器開發工具檢查頁面,可以看到 head 標籤也經過了定製化,同時 webpack 仍然將所有指令碼注入了頁面。

使用 poi.config.js 配置 Poi

上面配置 HTML 模板的方法對簡單的 JavaScript 頁面來說還比較好用,但是很快你就會需要一個能夠配置更多選項的方法。這時候就可以介紹 poi.config.js 了。

首先在專案目錄下新建 poi.config.js 檔案。其使用 module.exports 匯出一個配置物件:

module.exports = {
  html: {
    title: 'Running JavaScript Apps with Poi',
    description: 'Customize how to render the main template using configuration settings.',
    template: './index.ejs',
    text: 'Running JavaScript Apps with Poi',
    author: ['Rajat'],
  },
};
複製程式碼

·titledescription 用於定義頁面的標題的描述內容。template 選項用來告訴 Poi 將定製選項匯出到哪裡。

這裡將使用上一節已經建立的 index.ejs 檔案。現在將其內容修改為只包含一個 div 元素:

<div id="app"></div>
複製程式碼

我們需要在頁面 body 中渲染 textauthor 選項。在 index.ejs 內輸入以下程式碼:

<% const {text, author} = htmlWebpackPlugin.options %>
<h1>
  <%= text%>
</h1>
<ul>
  <% _.forEach(author, a => { %>
    <li>
      <%- a %>
    </li>
  <% })%>
</ul>
複製程式碼

這裡我們在模板中使用了 UnderscoreLodash 來獲取 textauthor 選項。

我們修改了配置,因此需要重新執行命令 poi 來檢視頁面的變化。

【譯】使用 Webpack 和 Poi 構建更好的 JavaScript 應用

注意這應該只被用來配置你的專案。資料之類的東西應該留給 JavaScript 來處理。

使用 Poi 構建 Vue 應用

Poi 的一大優勢在於我們可以在不必安裝 Vue 作為依賴的情況下用它來構建 Vue 應用。

這是由於 Poi 的開發者同時也是 Vue 的核心開發者之一,因此 Poi 預設已配置好可與 Vue 共同使用。

刪除專案目錄中的所有檔案。建立一個新的 index.js 檔案並且引入 Vue 包。

import Vue from 'vue';
import App from './App.vue';
new Vue ({
  el: "#app",
  render: h => h(App),
});
複製程式碼

上面的程式碼片段中,我們從 App.vue 檔案中引入了 App 元件,然後建立了 Vue 的一個例項並且掛載到 idappdiv 元素上。render 函式將渲染 App.vue 檔案中的程式碼:

<template>
  <h1>{{message}}</h1>
</template>
<script>
  export default {
    data() {
      return {
        message: 'Running Vue App with Poi!!',
      };
    },
  };
</script>
複製程式碼

重新執行命令 poi 然後你將看到一個完整的 Vue 應用在執行!

注意:如遇到“模組未發現”的錯誤提示,則在專案中安裝 Vue 依賴。

使用 Poi 構建 React 應用

使用 Poi 構建 React 同樣非常簡單。我們所需要做的就是安裝 reactreact-dom 包,以及配置 Babel 來處理程式碼。

首先,在專案中安裝 reactreact-dom

$ yarn add react react-dom
複製程式碼

在配置 Babel 之前,我們需要安裝一些開發依賴。

$ yarn add babel-preset-react-app babel-plugin-react-require -D
複製程式碼

然後建立名為 .babelrc 的檔案,內容如下:

{
  "presets": ["react-app"],
  "plugins": ["react-require"]
}
複製程式碼

現在,你就可以編寫你的 React 應用了!

在 Poi 中編譯樣式

在使用 Poi 構建的 React 應用中引入 CSS 樣式十分簡單。在專案目錄下建立一個 .css 檔案然後在 .js 檔案中編寫引入宣告即可。

但是如果使用 .scss 檔案來建立樣式,那麼就需要安裝一些依賴。

開啟終端然後使用 NPM/Yarn 安裝 node-sasssass-loader

$ yarn add node-sass sass-loader
// or
$ npm i node-sass sass-loader
複製程式碼

安裝完畢後,重新執行命令 poi,可以看到樣式已經載入到 React 應用中!

手動新增 Webpack Loader

Poi 是真的牛。它讓你不用再進行任何定製化或者配置就能使用大量的 webpack loader。

當然,Poi 也無法覆蓋到所有 webpack loader。下面的例子展示了通過新增 react-markdown-loader 到 Poi 可以將 Markdown 檔案載入為 React 元件。我們可以通過這個例子來看看如何手動新增 Webpack loader。

在專案目錄下建立名為 page.md 的新檔案並在該檔案中隨意書寫 markdown 格式的內容。

為了使 Poi 能夠處理 markdown 檔案,我們需要新增合適的 loader。

poi.config.js 中新增 webpack 屬性,如下所示:

module.exports = {
  webpack(config){
    config.module.rules.push({
      test: /\.md$/,
      loaders: [
        "babel-loader",        
        "react-markdown-loader"
      ] 
    })  
    return config
  }
}
複製程式碼

當然,確保你已經在專案中安裝 react-markdown-loader

經過以上處理後,在 index.js 中引入 markdown 頁面並且在渲染函式中將其以 React 元件的形式呼叫。

import {render} from 'react-dom'
import Page from './page.md'

render(<Page />, document.getElementById("app"));
複製程式碼

重新執行命令 poi,markdown 檔案將正常在瀏覽器算載入。

使用 Poi 構建 JavaScript 包

如要使用 Poi 打包 JavaScript 專案,只需在終端中執行命令 poi build,即可在專案目錄中得到 dist資料夾。

你可以使用命令 http-server dist 啟動 dist 資料夾。改命令將在 localhost:8080 上啟動專案。

如需分析你的專案,首先安裝開發依賴 webpack-bundle-analyzer

yarn add webpack-bundle-analyzer -D
複製程式碼

然後將其加入到 poi.config.js,如下所示:

const BundleAnalyzer = require("webpack-bundle-analyzer").BundleAnalyzerPlugin

module.exports = options => ({
  webpack (config) {
    if(options.analyze){
      config.plugins.push(
        new BundleAnalyzer()
      )
    }
    config.module.rules.push ({
      test: /\.md$/,
      loaders: ['babel-loader', 'react-markdown-loader'],
    });
    return config;
  },
})
複製程式碼

options 引數使得 analyze 函式可通過 options.analyze 來配置是否使用。因此,只有執行命令 poi build --analyze,Poi 才會執行 BundleAnalyzer 外掛。

【譯】使用 Webpack 和 Poi 構建更好的 JavaScript 應用

使用 Poi Presets 來跳過配置

之前提到,Poi 內建了 Vue 預設配置。除此之外,Poi 還提供了其他一些預設配置來讓我們安裝一些流行的庫,比如 Elm,React,StorybookTypeScript 等。

在終端中執行以下命令來在專案中安裝 poi-preset

$ yarn add @poi/plugin-<libary-name> --dev
複製程式碼

所以如果你想在專案中安裝 Elm,需要輸入的命令是 yarn add @poi/plugin-elm --dev

使用該外掛需要在 poi.config.js 中編寫以下程式碼:

module.exports = {
  plugins: [
    require('@poi/plugin-elm')(options)
  ]
}
複製程式碼

想要了解如何使用其他 poi-presets,查閱 github.com/egoist/poi/… 即可。

總結

如果你正在構建的應用具有許多非程式碼類的靜態資源,Webpack 能提供很大幫助。

另一方面,其他打包工具比如 GruntGulp,並沒有依賴關係圖的概念。

Webpack 具有很多的優點,因此它可能是你的專案的絕佳選擇。其在 React 社群也得到了廣泛的使用。

而 Poi 為我們提供了一種 “自由配置” 的方式來啟動 JavaScript 專案,這簡直就是錦上添花了!

本文首發於我的部落格(點此檢視),歡迎關注。

相關文章