從0到1基于Webpack的React項(xiàng)目搭建

剛參與了一個(gè)從頭開始搭建的項(xiàng)目,整理一下前端從0到1搭建的基于webpack的react項(xiàng)目實(shí)踐焚刺。(不用腳手架的那種哦)

創(chuàng)建一個(gè)新的文件夾以項(xiàng)目名命名

mkdir xiaoming
cd xiaoming

添加 package.json

npm init

在你的項(xiàng)目目錄文件下運(yùn)行 npm init, 結(jié)果如下圖

npm init

按照提示輸入(一般情況都是回車處理)后輸入yes就會(huì)生成package.json文件了。package.json 是項(xiàng)目的核心文件,包含包依賴管理和腳本任務(wù)。

現(xiàn)在你的項(xiàng)目長(zhǎng)這個(gè)樣子

xiaoming
└ package.json

使用自己喜歡的編輯器打開當(dāng)前repo查看生成的package.json文件

安裝依賴包

按照我們的標(biāo)題來看至少有兩個(gè)最基本的依賴需要安裝:react和webpack伯病。

安裝react

安裝react, 還需要安裝react-dom,react 從 0.14 版本開始否过,將 react-dom 拆分出 react 包午笛,所以現(xiàn)在需要單獨(dú)安裝。

npm i --save react react-dom

安裝webpack

這里 webpack-cli 作為一個(gè)命令行工具苗桂,接收一些參數(shù)并用于 webpack 的編譯器药磺,webpack-dev-server 是一個(gè)基于 express 的開發(fā)服務(wù)器,還提供了 live reloading 的功能煤伟,在開發(fā)的時(shí)候使用它配置熱加載癌佩。

npm i --save-dev webpack webpack-cli webpack-dev-server

在命令行運(yùn)行上面兩條命令后,package.json發(fā)生了變化便锨。多了dependenciesdevDependencies围辙。之后你安裝的所有依賴的名字和版本號(hào)都會(huì)出現(xiàn)在這個(gè)里面,便于管理放案。

package.json

安裝babel

通常我們?cè)趯憫?yīng)用的時(shí)候姚建,都會(huì)用到es6/7/8和jsx的一些語法,所以我們需要能夠編譯這些語法吱殉,就需要引入插件

npm i --save-dev babel-core babel-loader html-webpack-plugin

babel 插件是為了讓 webpack 能夠使用 babel 編譯 es6/7/8 和 jsx 的語法掸冤,而 html-webpack-plugin 會(huì)生成一個(gè) html 文件,它的內(nèi)容自動(dòng)引入了 webpack 產(chǎn)出的 bundle 文件友雳。

現(xiàn)在你的項(xiàng)目長(zhǎng)這個(gè)樣子

xiaoming
└ node_modules
└ package.json
└ package-lock.json

配置 webpack

首先你需要一個(gè)webpack.config.js稿湿,包含了你的webpack所有配置

  1. 在repo下新建webpack.config.js
  2. copy如下代碼進(jìn)webpack.config.js(關(guān)于webpack的配置網(wǎng)上一搜一大把,不贅述)
const HtmlWebPackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
// 以哪個(gè)模塊為入口
    index_bundle: './src/index.js',
  },
  output: {
// 打包好的文件存放在哪里沥阱,以及怎么命名
    path: path.join(__dirname, '/dist'),
    filename: 'bundle.js'
  },
  module: {
// 使用 babel-loader 編譯 es6/7/8 和 jsx 語法
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      }
    ]
  },
  plugins: [
    // 指定自己的 html 文件模板缎罢,也可以指定生成的 html 的文件名
    new HtmlWebPackPlugin({
      template: './src/index.html',
      filename: './index.html',
      favicon: './src/favicon.ico',
    }),
  ],
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          enforce: true,
          chunks: 'all'
        }
      }
    }
  }
};

現(xiàn)在你的項(xiàng)目長(zhǎng)這個(gè)樣子

xiaoming
└ node_modules
└ package.json
└ package-lock.json
└ webpack.config.js

看起來差不多了,現(xiàn)在來寫react的hello world好了

  1. 新建src文件夾
  2. 在src中新建App.js, index.html, index.js文件(參見react官網(wǎng)hello world代碼部分)
xiaoming
└ node_modules
└ src
  └ App.js
  └ index.html
  └ index.js
└ babel.config.js
└ package.json
└ package-lock.json
└ webpack.config.js

將package.json中的scripts添加一條命令:

"scripts": {
    "start": "webpack-dev-server --config webpack.config.js --open"
  },

下圖是我完整的package.json文件考杉,僅供參考

{
  "name": "xiaoming",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --config webpack.config.js --open"
  },
  "author": "xueying",
  "license": "ISC",
  "dependencies": {
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-redux": "^7.1.0",
    "redux": "^4.0.4"
  },
  "devDependencies": {
    "@babel/core": "^7.5.5",
    "@babel/preset-react": "^7.0.0",
    "@babel/preset-env": "^7.5.5",
    "babel-core": "^6.26.3",
    "babel-loader": "^8.0.6",
    "html-webpack-plugin": "^3.2.0",
    "webpack": "^4.35.0",
    "webpack-cli": "^3.3.5",
    "webpack-dev-server": "^3.7.2"
  }
}

babel.config.js

module.exports = {
  'presets': ['@babel/react','@babel/env'],
};

App.js

import React, {Component} from 'react';

class App extends Component {
  render() {
    return (
      <div className='app'>
        <h1>Hello world</h1>
      </div>
    );
  }
}

export default App;

index.html

<!doctype html>
<html lang="nl">
<head>
  <meta charset="UTF-8">
  <title>Welcome to Xiaoming hotpot</title>
</head>
<body>
  <div id="app"></div>
</body>
</html>

index.js

import React from 'react';
import {hydrate} from 'react-dom';
import App from './App';

hydrate(<App/>, document.getElementById('app'));

命令行運(yùn)行npm run start就可以啟動(dòng)你的demo,可以在瀏覽器中看見hello world了舰始。

hello world

周末閑來無事加上了前端項(xiàng)目docker化崇棠,讓其拿到repo后先執(zhí)行repo里的startLocal腳本啟動(dòng)docker,再在docker里運(yùn)行npm install等相關(guān)命令丸卷。目的主要是為了團(tuán)隊(duì)協(xié)作時(shí)防止每個(gè)人本地node版本不一致枕稀,install時(shí)改來改去,破壞環(huán)境。

創(chuàng)建docker-compose.yml

version: '2'
services:
    nginx:
        container_name: nginx
        image: nginx:1.16.1-alpine
        ports:
            - '8080:8080'
        volumes:
            - ./nginx.conf:/etc/nginx/conf.d/default.conf

    frontend:
        container_name: frontend
        image: node:10
        ports:
            - '3000:3000'
        volumes:
            - ./node_modules:/work/node_modules
            - ./:/work
        working_dir: '/work'
        command: ["bash"]
        stdin_open: true
        tty: true

創(chuàng)建nginx.conf

server {
    listen       8080;
    charset utf-8;
    server_name  0.0.0.0;

    location / {
        proxy_pass   http://frontend:3000;
        proxy_set_header Host $host;
    }

    location /api {
        proxy_pass   http://你的后端host/;
    }
}

創(chuàng)建本地一鍵啟動(dòng)腳本 ./startLocal.sh

#!/usr/bin/env bash
docker-compose -f ./docker-compose.yml -p . up -d
docker exec -it frontend /bin/bash
docker-compose -f ./docker-compose.yml -p .  down

一鍵啟動(dòng)步驟

git clone git@github.com:lixueying/react-with-webpack.git
cd react-with-webpack
./startLocal.sh
npm install (只在第一次進(jìn)入docker或者依賴有更新的時(shí)候使用)
npm start

repo下載之后就可以直接用了萎坷,不需要自己再去搭架子凹联,開箱即用。

附上React簡(jiǎn)易腳手架的GitHub地址:https://github.com/lixueying/react-with-webpack

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末哆档,一起剝皮案震驚了整個(gè)濱河市蔽挠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瓜浸,老刑警劉巖澳淑,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異插佛,居然都是意外死亡杠巡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門雇寇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來氢拥,“玉大人,你說我怎么就攤上這事锨侯⌒忠唬” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵识腿,是天一觀的道長(zhǎng)出革。 經(jīng)常有香客問我,道長(zhǎng)渡讼,這世上最難降的妖魔是什么骂束? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘朱庆。我一直安慰自己摹闽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布系草。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪栖榨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天明刷,我揣著相機(jī)與錄音婴栽,去河邊找鬼。 笑死辈末,一個(gè)胖子當(dāng)著我的面吹牛愚争,可吹牛的內(nèi)容都是我干的映皆。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼轰枝,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼捅彻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鞍陨,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤步淹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后湾戳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贤旷,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年砾脑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了幼驶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡韧衣,死狀恐怖盅藻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情畅铭,我是刑警寧澤氏淑,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站硕噩,受9級(jí)特大地震影響假残,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜炉擅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一辉懒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谍失,春花似錦眶俩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至抹竹,卻和暖如春线罕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背柒莉。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工闻坚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人兢孝。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓窿凤,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親跨蟹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子雳殊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345