【webpack系列】從零搭建 webpack4+react 腳手架(一)

搭建一個React工程的方式有不少,官方也有本身的腳手架,若是你和我同樣,喜歡刨根究底,從零開始本身一行一行代碼建立一個React腳手架項目,那你就來對地方了。本教程是針對React新手,以及對webpack還不熟悉的用戶,或者是想了解當前前端工程化方案的用戶。我會在整個系列經過webpack4的配置,從生產和開發環境分別入手,包含代碼壓縮,大文件gz壓縮,webpack4的code split,postcss等插件如何引入,css編譯,如何讓環境支持各類css預處理器,cssModule配置化,bundle結果分析,本地代理配置,React相關技術棧等等都有一個講解。本系列教材由淺入深,將會從零開始一步步完善整個腳手架。css

前提條件

在開始以前,請確保安裝了 Node.js 的最新版本。建議使用 Node.js 最新的長期支持版本(LTS - Long Term Support)。若是你使用舊版本,你可能遇到各類問題,由於它們可能缺乏 本教程用到的相關的 package 包。html

執行如下命令能夠查看你本機安裝的node版本:
node -v && npm -v
若是你本機的node版本不是最新的,建議升級到新的node版本。node版本建議經過nvm進行管理,瞭解能夠查看 http://nvm.sh 這裏再也不闡述。前端

 

經過本課程,你會學到什麼?
學習完本系列教程,你將會了解(持續更新):
  1. 前端開發的框架,工程化的方式
  2. webpack4的基礎配置以及經常使用的一些插件
  3. postcss的使用,以及經常使用的postcss插件
  4. 開發環境和生產環境的腳本的不一樣
  5. 如何讓控制檯輸出編譯結果更加高大上
  6. 大文件如何進行gz壓縮
  7. 讓css Module可配置化
  8. 接口轉發
  9. 如何進行bundle分析
  10. 如何規範代碼,如何更好地整合eslint。
  11. 如何測試React代碼
1.從空文件夾開始
 
如今建立一個空的文件夾,用你的開發工具打開它。
打開終端,確保你已經進入剛剛建立的目錄,接下去執行:
npm init

終端會讓你輸入一些信息,好比名字,版本,描述,入口文件等等。 完成後,npm會自動在你的根目錄生成 package.json 文件。package.json 文件不只僅包含項目的配置信息(好比名稱、版本、許可證等元數據),還會記錄項目所須要的各類模塊,以及項目運行的腳本等等。node

 

2.安裝webpack4
 
本教程使用webpack來管理react工程。
執行如下命令,安裝webpack
npm install --save-dev webpack

npm安裝的包會存放在一個叫node_modules文件夾。若是你用的npm版本是npm 5版本,你還會發現多了package-lock.json文件。package-lock.json文件是當 node_modules 或 package.json 發生變化時自動生成的文件,它的主要功能是肯定當前安裝的包的依賴,以便後續從新安裝的時候生成相同的依賴,而忽略項目開發過程當中有些依賴已經發生的更新(翻譯自官方說明)。react

打開package.json,你會發現多了一個名爲devDependencies的屬性,經過--save-dev安裝的包會記錄在此屬性下。後續咱們還會使用--save去安裝一個模塊包,區別是經過--save安裝的模塊會記錄在dependencies屬性內,而不是devDependencies屬性。經過字面意思,你應該也能夠知道,一個是dev開發時候的依賴,一個是運行時的依賴。webpack

新建webpack配置文件。webpack 的配置文件,是導出一個對象的 JavaScript 文件。在根目錄建立build文件夾,添加一個js文件,命名爲webpack.base.conf.js。
手動敲入如下代碼:web

const path = require('path'); const DIST_PATH = path.resolve(__dirname, '../dist'); module.exports = { entry: { app: './app/index.js' }, output: { filename: "js/bundle.js", path: DIST_PATH } };

webpack 配置是標準的 Node.js CommonJS 模塊,它經過require來引入其餘模塊,經過module.exports導出模塊,由 webpack 根據對象定義的屬性進行解析。npm

這裏定義了2個屬性。固然,webpack的配置屬性遠遠不止這2個,以後我會深刻講解更多屬性的配置。回到咱們定義的2個屬性,entry定義了入口文件,output定義了編譯後的輸出。按照對這段代碼的理解,它應該是告訴webpack,我這個項目入口文件是app目錄下的index.js文件,你編譯後,在根目錄下建立dist文件夾(若是不存在),最後把編譯後的文件輸出到dist文件下,命名爲bundle.js。json

webpack4.0還增長了mode屬性,用來表示不一樣的環境。
咱們使用merge的方式來組織webpack基礎配置和不一樣環境的配置。
先安裝webpack-merge:前端工程化

npm install --save-dev webpack-merge

在build文件夾中再添加一個js文件,命名爲webpack.prod.conf.js,輸入如下代碼。

const merge = require('webpack-merge'); const baseWebpackConfig = require('./webpack.base.conf'); module.exports = merge(baseWebpackConfig, { mode: 'production' });

在根目錄下建立app目錄,而後建立index.js文件。

var element =document.getElementById('root'); element.innerHTML = 'hello, world!';

在根目錄建立一個public文件夾,而後新建一個index.html文件。

<!DOCTYPE html>
    <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>從零開始搭建react工程</title>
      </head>
      <body>
      <div id="root"></div>
      <script src="../dist/js/bundle.js"></script>
      </body>
    </html>

你如今的文件路徑應該看起來是這樣:(顯然咱們引用的bundle.js並不存在)

|- /app |- index.js |- /node_modules |- /public
        |- index.html |- /build |- webpack.base.conf.js |- webpack.prod.conf.js |- package.json |- package-lock.json

接下去咱們要經過執行webpack命令,來編譯咱們的代碼,生成bundle.js。4.0版本以後的webpack,已經將webpack命令工具遷移到webpack-cli模塊了。你須要安裝webpack-cli。

npm install --save-dev webpack-cli

安裝完成後,執行下面腳本進行編譯:

webpack --config build/webpack.prod.conf.js

編譯完成後,刷新根目錄,能夠看到已經生成dist文件夾和bundle.js文件。
用瀏覽器打開html文件,你會看到hello webpack。咱們成功經過webpack編譯了js文件,而且沒有出現問題。
webpack --config build/webpack.prod.conf.js命令,咱們能夠經過npm scripts管理起來。
在package.json文件,咱們爲scripts屬性配置一個build命令,其值爲:webpack --config build/webpack.prod.conf.js,如下是scripts的相關代碼:

"scripts": { "build": "webpack --config build/webpack.prod.conf.js", "test": "echo \"Error: no test specified\" && exit 1" },

 而後在命令行輸入:

npm run build

咱們能夠看到,webpack從新進行了編譯,這和執行
webpack --config build/webpack.prod.conf.js 是同樣的效果。

3.安裝react
 
在終端輸入如下命令:
npm install --save react react-dom

安裝成功後,咱們在項目使用react,咱們直接修改app目錄下的index.js的代碼,咱們用react來插入這句hello world!

import React from "react"; import ReactDom from "react-dom"; ReactDom.render( <h1>hello, world!</h1>, document.getElementById("root") );

好了,咱們再編譯試試看。

npm run build

失敗了?對不對!首先,我告訴你這段代碼沒有任何問題,你須要思考下,它爲何會編譯失敗。下一小節,咱們一塊兒來了解下緣由。

 

4.整合babel 7.0
 
爲何會失敗?由於webpack只識別JavaScript文件,並且只能編譯es5版本的JavaScript語法。實際上,咱們使用ES2015,以及jsx的語法糖,webpack它根本不認識啊。怎麼辦?webpack 可使用 loader 來預處理文件。它不只僅能夠處理JavaScript自己,還容許你打包任何的靜態資源。
其中,babel-loader,就是這樣一個預處理插件,它加載 ES2015+ 代碼,而後使用 Babel 轉譯爲 ES5。咱們來了解下如何在webpack配置babel-loader。
首先安裝babel相關的模塊:
npm install --save-dev babel-loader @babel/preset-react @babel/preset-env @babel/core

除了babel-loader,咱們還安裝了好多的包,其中@babel/core是babel的核心模塊,@babel/preset-env是轉譯ES2015+的語法,@babel/preset-react是轉譯react的JSX以及FLOW。瞭解詳情能夠移步 babel官方。
第二步,你須要在根目錄創建一個.babelrc的文件,配置相關的presets:

 { "presets": [ [ "@babel/preset-env", { "targets": { "browsers": [ "> 1%", "last 5 versions", "ie >= 8" ] } } ], "@babel/preset-react" ] }

更多關於babel的配置能夠看下官方http://babeljs.io/docs/en的說明,這裏再也不闡述。

第三步,修改webpack.base.conf.js文件。

const path = require('path'); const APP_PATH = path.resolve(__dirname, '../app'); const DIST_PATH = path.resolve(__dirname, '../dist'); module.exports = { entry: { app: './app/index.js' }, output: { filename: 'js/bundle.js', path: DIST_PATH }, module: { rules: [ { test: /\.js?$/, use: "babel-loader", include: APP_PATH } ] } };

在 webpack 配置中定義 loader 時,要定義在 module.rules 中。其中,test和use屬性是必須的。include屬性,定義了rules執行的範圍。這告訴 webpack 編譯器以下信息:
嘿,webpack 編譯器,你在編譯文件過程當中,若是這個是在app目錄下的js文件,在你對它打包以前,先使用 babel-loader 轉換一下。
從新執行本地編譯

npm run build

此次再也不報錯,編譯成功。
好了,再次打開public目錄的index.html,頁面成功顯示了hello world。
可能,你還有一些疑惑,html文件如何也同步到dist目錄?bundle.js文件修改了,萬一被瀏覽器緩存了怎麼辦?如何經過script標籤把打包生成的js自動添加到html?react和業務代碼如何分開打包?如何實現開發環境的熱更新?

下一章,我將針對這些問題,會一一進行講解,而且持續優化咱們的工程。

原文出處:https://www.cnblogs.com/nianzhilian/p/10229052.html

相關文章
相關標籤/搜索