將typescript+react的webpack專案遷移到parcel

jackple發表於2017-12-25

parcel簡介

Parcel, 是一個網路應用打包工具, 適用於經驗不同的開發者. 它利用多核處理提供了極快的速度, 並且不需要任何配置.

專案github地址

現狀

對於現階段來說, 對已有的成熟的webpack專案, 玩一下還是可以的, 但是不建議公司專案遷移, 坑必須還是很多的.

極速?

有對比才有傷害, 以下是我針對上面的兩個自己的github專案做的對比(都是跑生成環境):

首次:
webpack:
Hash: 934e621452b0231ded89
Version: webpack 3.8.1
Time: 8981ms

parcel:
built in 15.56s.

第二次:
webpack:
Hash: 934e621452b0231ded89
Version: webpack 3.8.1
Time: 9065ms

parcel:
Built in 3.41s.
複製程式碼

parcel在第二次利用cache的情況下, 速度還是有很大優勢的

零配置?

這個零配置不可以一概而論, 比如專案中有用到css module, babel的, 還是要配置的, 這個視乎使用者怎麼看, 不過確實比webpack少配置很多

遷移過程中需要改的

首先要說明一下, 這是基於ts-react(webpack)修改的, 遇到的問題並不一定與大家的相吻合

ts-loader -> babel

parcel內建babel, 編譯的過程中會呼叫babel去轉譯程式碼

webpack.DefinePlugin -> 啟動前設定procee.env

webpack定義全域性變數使用的是DefinePlugin, parcel沒有提供類似的方式, 只能在啟動前設定

cross-env APP_ENV=dev BASE_URL=http://rap2api.taobao.org parcel serve index.html -o
複製程式碼

不過現在新開了一個issue, 利用.env去實現, 估計很快能用.

css module

webpack專案中通過對應loader以及"modules"關鍵字的方式實現, 現在改由僅.postcssrc配置實現, 這個方法有一個缺點, 一旦設定, 就是全域性的, 檢視issue

另外還有一個生成css module definition的問題, webpack專案中通過typings-for-css-modules-loader(其實體驗不太好), 現在改由typed-css-modules通過命令列生成, 現在是新開一個命令列視窗去執行(npm run by package.json)

"tcm": "tcm src -c -w",
複製程式碼

import

webpack允許使用者import一個模組時使用非標準的路徑, 比如

import 'styles/app.scss'
複製程式碼

也可以在webpack配置中宣告alias

alias: {
    'assets': resolve('src/assets')
}
複製程式碼

在parcel中, 我們就必須把專案視為一個標準的node工程, 所有的匯入匯出都必須遵循標準語法

typescript dynamic import

webpack2,3在動態載入模組這一個功能點上較webpack1強大了許多, 剛剛出來時吹的很厲害, 支援了包括System.import這樣的語法, 可是這畢竟是基於SystemJS的語法, 在parcel中就不適用了, 不過可以直接使用import, 這個問題不是很大, 同時需要修改tsconfig

"compilerOptions": {
    "module": "esnext"
    ...
複製程式碼

sourceMaps

暫不支援, 檢視issue, 這個會是很多人止步的原因

react-hot-loader

webpack中的使用方式為:

  1. 修改webpack entry
entry: {
    app: [
      'react-hot-loader/patch',
      'webpack-hot-middleware/client',
      './src/index.tsx'
    ]
  }
複製程式碼
  1. 入口修改
import { AppContainer } from 'react-hot-loader'

const render = (Component) => {
  ReactDOM.render(
    <Provider {...store}>
      <AppContainer warnings={false}>
        <Component />
      </AppContainer>
    </Provider>,
    document.getElementById('app') as HTMLElement
  )
}

render(App)

// Hot Module Replacement API
if (module.hot) {
  module.hot.accept(['router'], () => {
    const NextApp = require<RequireImport>('router').default
    render(NextApp)
  })
}
複製程式碼

parcel的使用方式為有兩種:

  1. 入口處修改
import('react-hot-loader/patch')
複製程式碼
  1. 修改.babelrc
{
  "plugins": [
    ...
    "react-hot-loader/patch"
  ],
  ...
}
複製程式碼

這個配置就算是非常簡單了, 個人用的是第2種

總結

相對於webpack而言, parcel的配置成本會低一點, 可是, 配置成本不代表使用成本, 在實際專案中, 應用構建的過程可能需要額外做的一些工作, 在webpack上可能實現起來很方便, 可是用parcel就必須要寫外掛才能實現, 那算起來, 這也是一種額外的成本

parcel github少兩天沒看又多了將近1000star, 確實很了不起, 前景個人認為還是槓槓的. 風暫時都是國外同行在吹, 使用過程中遇到得很多問題, google用中文搜的話建議你還是放棄吧.

有說錯的地方還請指出, 見諒!

相關文章