可前往個人Github/blog進行閱讀,如有幫助,賞個star😊javascript
若是你和我同樣學習了webpack相關的教程,並跟着webpack官方指南進行了一些簡單的配置,可是不知道如何去使用它,那麼這個系列的文章將經過搭建webpack+react腳手架給予你必定的配置經驗,寫這個系列的文章一是爲了方便之後本身有配置需求時能夠及時回顧,二是增強本身對於webpack的理解。我會盡量詳細地一步一步講解這個腳手架配置步驟,也會對一些須要注意的點進行提醒,但願能幫助到你們~html
node -v
查看當前版本,若沒有安裝或不是最新版本,這裏提供Node.js官網以便下載讓咱們在桌面建一個空文件夾,名爲 webpck-react-scaffold
,並使用你的編輯器打開它。
將此文件夾拖到終端,執行:java
npm init -y
複製代碼
上面命令會在你的根目錄生成 package.json
文件,該文件定義了這個項目所須要的各類模塊,以及項目的配置信息(好比名稱、版本、許可證等元數據)。npm install
命令根據這個配置文件,自動下載所需的模塊,也就是配置項目所需的運行和開發環境。node
由於咱們使用的是 webpack 4+
版本,還須要安裝 webpack-cli
,執行如下命令:react
npm install --save-dev webpack webpack-cli
複製代碼
安裝完成,你會發如今 package.josn
中多了一個 devDependencies
屬性,這是由於咱們安裝依賴包時 --save-dev
的結果,這表明了開發時的依賴。以後咱們會只用 --save
安裝依賴包,這表明了運行時依賴。webpack
咱們確認一下,如今根目錄下的文件結構以下:git
webpack-react-scaffold
|- node_modules
|- package.json
複製代碼
接下來,咱們在根目錄下新建一個文件夾名爲 config
用於存放配置文件,在此文件夾下建立一個 .js
文件名爲 webpack.common.config.js
,敲入如下代碼:github
const path = require('path');
module.exports = {
entry: {
app: './src/app.js',
},
output: {
filename: 'js/bundle.js',
path: path.resolve(__dirname, '../dist')
}
}
複製代碼
webpack 配置是標準的 Node.js的CommonJS 模塊,它經過require來引入其餘模塊,經過module.exports導出模塊,由 webpack 根據對象定義的屬性進行解析。web
entry
屬性定義了入口文件路徑, output
定義了編譯打包以後的文件名以及所在路徑。
這段代碼的意思是告訴webpack,入口文件是 src
目錄下的 app.js
文件。打包輸出的文件名字爲 bundle.js
,保存在上一級目錄下的 dist
文件夾中。chrome
咱們建立一個文件夾名爲 src
,在其中新建一個js文件名爲 app.js
,如今咱們的目錄結構以下:
webpack-react-scaffold
+ |- config
+ |- webpack.common.config.js
|- node_modules
+ |- src
+ |- app.js
|- package.json
複製代碼
那咱們怎麼打包呢?在 package.json
中配置以下屬性:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
+ "start": "webpack --config ./config/webpack.common.config.js"
},
複製代碼
好了,咱們試試怎麼打包吧,雖然你的 app.js
中什麼代碼也沒有。
在控制檯中輸入如下代碼:
npm run start
複製代碼
想必你也看出來了,爲何是 「start」,--config
選項來指定配置文件。
執行以後,你會發現根目錄多出了一個文件夾: dist/js
,其中有一個js文件: bundle.js
,那麼至此,咱們已經成功編譯打包了一個js文件,即入口文件: app.js
。
咱們將使用一個名爲 webpack-merge 的工具。經過「通用」配置,咱們沒必要在環境特定(environment-specific)的配置中重複代碼。簡單來講就是生產環境不一樣,咱們要給的配置也有所不一樣,可是能夠共用一個共有的配置。
咱們先從安裝 webpack-merge 開始:
npm install --save-dev webpack-merge
複製代碼
安裝結束以後,咱們在 config
這個文件夾下新建兩個文件,分別爲 webpack.prod.config.js
和 webpack.dev.config.js
,這兩個文件分別對應生產和開發兩個環境的配置。
如今的目錄結構:
webpack-react-scaffold
|- config
|- webpack.common.config.js
+ |- webpack.prod.config.js
+ |- webpack.dev.config.js
|- node_modules
|- src
|- app.js
|- package.json
複製代碼
在 webpack.prod.config.js
中輸入如下代碼:
const merge = require('webpack-merge');
const common = require('./webpack.common.config.js');
module.exports = merge(common, {
mode: 'production',
});
複製代碼
回到咱們以前建立的 app.js
文件,輸入代碼:
var root =document.getElementById('root');
root.innerHTML = 'hello, webpack!';
複製代碼
在根目錄下建立一個文件夾名爲: public
,再新建一個html文件,名爲: index.html
,如下內容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>從零配置webpack4+react腳手架</title>
</head>
<body>
<div id="root"></div>
<script src="../dist/js/bundle.js"></script>
</body>
</html>
複製代碼
如今的目錄結構是這樣子(只要不編譯打包,要引入的 bundle.js
就沒有):
webpack-react-scaffold
|- config
|- webpack.common.config.js
|- webpack.prod.config.js
|- webpack.dev.config.js
|- node_modules
+ |- public
+ |- index.html
|- src
|- app.js
|- package.json
複製代碼
打包以前,咱們修改 package.json
:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
- "start": "webpack --config ./config/webpack.common.config.js",
+ "build": "webpack --config ./config/webpack.prod.config.js"
},
複製代碼
好了,接下來咱們編譯打包試試吧!控制檯執行如下代碼:
npm run build
複製代碼
咱們能夠看到,webpack從新進行了編譯,這和執行webpack --config config/webpack.prod.conf.js
是同樣的效果。
如今你能夠打開用瀏覽器 public/index.html
,看看是否是有東西了~~
在控制檯輸入如下代碼:
npm install --save react react-dom
複製代碼
安裝完成以後,咱們就能夠寫react的JSX語法了。
這裏爲了和react官方腳手架 create-react-app
的目錄結構相相似,咱們在 src
文件夾下新建一個js文件, index.js
,用於渲染根組件。
在 index.js
輸入如下代碼:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root')); 複製代碼
並用jsx語法重寫 app.js
:
import React from 'react';
function App() {
return (
<div className="App">Hello World</div>
);
}
export default App;
複製代碼
對 webpack.common.config.js
文件中的入口進行修改,由於咱們如今要編譯打包的應該 index.js
:
const path = require('path');
module.exports = {
entry: {
- app: './src/app.js',
+ index: './src/index.js',
},
output: {
filename: 'js/bundle.js',
path: path.resolve(__dirname, '../dist')
}
}
複製代碼
如今嘗試一下從新運行 npm run build
,會發現打包失敗了,爲何呢?接着看.....
爲何咱們上面寫jsx會打包不了呢,由於webpack根本識別不了jsx語法,那怎麼辦?使用loader對文件進行預處理。
其中,babel-loader,就是這樣一個預處理插件,它加載 ES2015+ 代碼,而後使用 Babel 轉譯爲 ES5。那開始配置它吧!
首先安裝babel相關的模塊:
npm install --save-dev babel-loader @babel/preset-react @babel/preset-env @babel/core
複製代碼
理論上咱們能夠直接在 webpack.common.config.js
中配置"options",但最好在當前根目錄,注意,必定要是根目錄!!! 新建一個配置文件 .babelrc
配置相關的"presets":
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
// 大於相關瀏覽器版本無需用到 preset-env
"edge": 17,
"firefox": 60,
"chrome": 67,
"safari": 11.1
},
// 根據代碼邏輯中用到的 ES6+語法進行方法的導入,而不是所有導入
"useBuiltIns": "usage"
}
],
"@babel/preset-react"
]
}
複製代碼
這裏有關bebel的配置可上官網查詢文檔。
再修改 webpack.common.config.js
,添加以下代碼:
const path = require('path');
module.exports = {
entry: {
index: './src/index.js',
},
output: {
filename: 'js/bundle.js',
path: path.resolve(__dirname, '../dist')
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader',
exclude: /node_modules/,
}
]
}
}
複製代碼
test
規定了做用於以規則中匹配到的後綴結尾的文件, use
便是使用 babel-loader
必須的屬性, exclude
告訴咱們不須要去轉譯"node_modules"這裏面的文件。
接下來:
npm run build
複製代碼
是否是能打包成功了呢?回到你的html頁面,看一下是否打印出了「hello webpack」吧!
咱們再最後確認一下咱們的目錄:
webpack-react-scaffold
|- config
|- webpack.common.config.js
|- webpack.prod.config.js
|- webpack.dev.config.js
|- node_modules
|- public
|- index.html
|- src
+ |- index.js
|- app.js
+ |- .babelrc
|- package.json
複製代碼
這一小節就到這裏,你會發現有不少功能仍是沒有得以實現,好比自動生成html文件,實時刷新頁面等,下一節開始咱們會逐步優化咱們的配置!