基於webpack的React項目搭建(一)


 

前言 

工欲善其事,必先利其器。為了更好的學習React,我們先簡要的把開發環境搭建起來。本文主要介紹使用webpack搭建React項目,如果你對React或es6的基礎語法還不了解,建議先去學習學習。

 

鑒於文章發布到現在已有一年之久,很多庫版本也發生了很多變化,也導致了很多新手搭建出現許多問題。最近已將舊版本全面升級,項目架構也有所調整,開發環境保留了node啟動和webpack啟動webpack-dev-server,沒有加入狀態管理和ajax請求,eslint支持react-hooks,諸位可根據自身需求添加或修改即可。希望新版的調整能幫助各位節省搭建時間,享受代碼的樂趣。新版地址: https://github.com/cy6121/first-react,如果遇到任何問題,歡迎👏提issues。

  • 基礎環境

node/npm

  • webpack

現代JavaScript程序應用的模塊打包器。它主要分析你的項目結構,找到JavaScript模塊以及其他一些瀏覽器不能直接運行的拓展語言(Scss、less、TypeScript),將其轉換和打包為合適的格式供瀏覽器使用。

  • 項目創建

創建一個文件夾first-react,進入該目錄,在該目錄下打開一個終端,執行npm init。根據提示輸入內容,也可以直接按回車鍵跳過。執行完后目錄中會多一個package.json文件,這是項目的核心文件,包含包依賴管理和腳本任務。 

mkdir first-react
cd first-react 
npm init
  • 安裝react, react-dom, webpack

在項目根目錄下執行下面命令,其中--save的含義是項目上線運行所需的包,即生產環境(--save-dev是開發環境所需的包)。

npm install react react-dom --save
npm install webpack --save-dev
  •  項目目錄和源碼

--your project
   |--dist(項目打包輸出目錄)
       |--bundle.js(該文件是由webpack打包生成)
       |--index.html  
   |--src
       |--index.js
   |--webpack
       |--webpack.config.js
   |--package.json       

  index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
    /* react DOM*/
    </div>
    <script src="bundle.js"></script>
</body>
</html>

  index.js

import React, { Component } from 'react';
import { render } from 'react-dom';

render(
    <div>Hello React!</div>,
    document.getElementById('app')
);

  webpack.config.js

const path = require('path');
module.exports = {
    entry: path.resolve(__dirname, '../src/index.js'), //指定入口文件,程序從這里開始編譯,__dirname當前所在目錄, ../表示上一級目錄, ./同級目錄
    output: {
        path: path.resolve(__dirname, '../dist'), // 輸出的路徑
        filename: 'bundle.js'  // 打包后文件
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['es2015', 'react'],
                    }
                },
                exclude: /node_modules/
            }
        ]
    }
}

這里如果在項目根目錄直接進行webpack構建會報錯(構建命令:webpack --config webpack/webpack.config.js),因為我們使用了react,react是使用jsx語法實現的,而jsx不能直接被瀏覽器識別和執行,所以這里需要引入Babel庫進行轉碼。

npm install babel-core babel-loader babel-preset-es2015 babel-preset-react --save 

  babel-loader: babel加載器

  babel-preset-es2015: 支持es2015

  babel-preset-react: jsx 轉換成js

最后再次進行構建,然后點擊build/index.html,即可看到Hello React!

webpack --config webpack/webpack.config.js // 更多webpack命令盡在webpack --help查閱, 如果出現webpack: command not found, 全局安裝webpack即可, npm install webpack -g;
// 當然你喜歡用腳本的方式執行,則無需安裝。但是需要注意在webpack4中需要安裝webpack-cli, npm install webpack-cli --save-dev。

  接下來我們進行一下簡單的優化,執行效果一致。

index.js

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

const renderDom = Component => {
    render(
        <Component />,
        document.getElementById('app')
    );
}
renderDom(App);

 在項目根目錄下新建json文件.babelrc,將babel的配置單獨提取出來。

{
  "presets": [
    "es2015",
    "react"
  ]
}

webpack.config.js文件作相應的調整。

const path = require('path');
const webpack = require('webpack');
module.exports = {
    entry: path.resolve(__dirname, '../src/index.js'), //指定入口文件,程序從這里開始編譯,__dirname當前所在目錄, ../表示上一級目錄, ./同級目錄
    output: {
        path: path.resolve(__dirname, '../dist'), // 輸出的路徑
        filename: 'bundle.js'  // 打包后文件
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            }
        ]
    }
}

在src下新建App.js。

import React, { Component } from 'react';

export default class App extends Component {
    render() {
        return (
            <div>Hello React!</div>
        );
    }
}
  •  以腳本方式執行構建

編輯package.json,加入自定義腳本,在項目根目錄執行npm run dev即可達到上面一樣的效果。

"scripts": {
    "dev": "webpack --config webpack/webpack.config.js"
  }
  •  搭建前端服務器

可以發現,每次都要重新構建然后刷新index.html,才能得到最新的效果,開發效率極低。幸好webpack-dev-server可以幫助我們解決這個問題,webpack-dev-server是一個小型的靜態文件服務器,為webpack打包的資源文件提供Web服務。並且提供自動刷新和Hot Module Replacement(模塊熱替換:前端代碼變動后無需刷新整個頁面,只把變化的部分替換掉)。OK,讓我們開始安裝和配置webpack-dev-server。

npm install webpack-dev-server --save-dev  

 在項目根目錄下創建bin目錄,進入bin目錄,創建dev-server.js文件,編輯如下

'use strict'

const WebpackDevServer = require('webpack-dev-server');
const config = require('../webpack/webpack.config');
const webpack = require('webpack');
const path = require('path');
const compiler = webpack(config);

const server = new WebpackDevServer(compiler, {
    contentBase: path.resolve(__dirname, '../dist'), //默認會以根文件夾提供本地服務器,這里指定文件夾
    historyApiFallback: true, //在開發單頁應用時非常有用,它依賴於HTML5 history API,如果設置為true,所有的跳轉將指向index.html
    port: 9090, //如果省略,默認8080
    publicPath: "/"
});
server.listen(9090, 'localhost', function (err) {
    if (err) throw err
})

   編輯package.json,創建一條腳本

"scripts": {
    "dev": "node bin/dev-server"
  }

   最后,單獨在該項目根目錄起一個終端,執行npm run dev,啟動成功后訪問http://localhost:9090。如果看到Hello React!,恭喜你。 最后再做一下簡單的測試,將App.js修改如下后保存,可以發現,項目會自動重新編譯運行,刷新瀏覽器即可看到最新的更改。

import React, { Component } from 'react';

export default class App extends Component {
    render() {
        return (
            <div>
                <h1>Hello React</h1>
                <h2>Hello React</h2>
            </div>
        );
    }
}
  • Html-webpack-plugin

  刪除根目錄下dist目錄,剛剛我們是自己編寫和配置index.html,將打包后的js引入到index.html中。現刪除后啟動服務會報錯,現在我們使用插件實現自動引入,免去手工配置,安裝html-webpack-plugin

npm install html-webpack-plugin --save-dev

  在src目錄新建index.template.html。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title><%= htmlWebpackPlugin.options.title %></title>
    </head>
    <body>
        <div id="app">
        </div>
    </body>
</html>

  編輯webpack.config.js。最后重新啟動服務即可。若是想看打包后的文件可以打開chorme,在Sources即可看見。或者使用webpack --config webpack/webpack.config.js進行構建,在項目目錄的dist目錄查看。

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports
= { entry: path.resolve(__dirname, '../src/index.js'), //指定入口文件,程序從這里開始編譯,__dirname當前所在目錄, ../表示上一級目錄, ./同級目錄 output: { path: path.resolve(__dirname, '../dist'), // 輸出的路徑 filename: 'app/[name]_[hash:8].js' // 打包后文件 }, module: { rules: [ { test: /\.(js|jsx)$/, loader: 'babel-loader', exclude: /node_modules/ } ] },
   plugins: [
     new HtmlWebpackPlugin({
       template: path.resolve(__dirname, '../src/index.template.html'),
       inject: true

     })
   ]
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM