一:廢話不多說,直接干起來
1:我們先創(chuàng)建一個react項目,使用最基礎(chǔ)的方式創(chuàng)建牵寺,終端執(zhí)行 npm init
械姻,按照提示妒蛇,最后會創(chuàng)建一個 package.json
的文件
npm init
2:添加必要的依賴庫 cnpm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/preset-react
babel 用來將ES6 轉(zhuǎn)換為 ES5,和轉(zhuǎn)譯 react 代碼
2.1:添加webpack打包依賴 cnpm install --save-dev webpack webpack-cli webpack-dev-server webpack-node-external style-loader css-loader babel-loader
2.2:添加 react 依賴 install --save-dev react react-dom
執(zhí)行完成后楷拳,我們的 package.json 的內(nèi)容如下
{
"name": "myfirstcompent",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"@babel/preset-react": "^7.9.4",
"babel-loader": "^8.1.0",
"css-loader": "^3.5.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"style-loader": "^1.1.4",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3",
"webpack-node-externals": "^1.7.2"
}
}
二:開始構(gòu)建項目結(jié)構(gòu)
1:在當(dāng)前目錄下創(chuàng)建兩個文件夾 public
和 src
然后在 public
里創(chuàng)建 index.html
文件
+-- public
+-- src
index.html 中的內(nèi)容
<!-- sourced from https://raw.githubusercontent.com/reactjs/reactjs.org/master/static/html/single-file-example.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>React Starter</title>
</head>
<body>
<div id="root"></div>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<script src="../dist/bundle.js"></script>
</body>
</html>
接著在 src
下創(chuàng)建 index.js绣夺、App.js、App.css
三個文件
index.js 內(nèi)容
import React from "react";
import ReactDOM from "react-dom";
import App from "./App.js";
ReactDOM.render(<App />, document.getElementById("root"));
App.js 內(nèi)容
import React, { Component} from "react";
import "./App.css";
class App extends Component{
render(){
return(
<div className="App">
<h1> Hello, World! </h1>
</div>
);
}
}
export default App;
App.css 內(nèi)容
.App {
margin: 1rem;
font-family: Arial, Helvetica, sans-serif;
}
這時候的目錄結(jié)構(gòu)如下:
+-- node_modules
+-- public
| +-- index.html
+-- src
| +-- App.css
| +-- App.js
| +-- index.js
+-- package.json
三:添加打包的配置文件
1:在根目錄下創(chuàng)建webpack的配置文件欢揖,這里分開發(fā)環(huán)境的配置和發(fā)布環(huán)境的配置
開發(fā)環(huán)境: webpack.dev.js
開發(fā)環(huán)境:webpack.dev.js 內(nèi)容 陶耍,這個名稱好像不能亂改,我直接寫成webpack.config.dev.js 一直報錯
-----------------------
RROR in ./src/index.js 5:16
Module parse failed: Unexpected token (5:16)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| import App from "./App.js";
|
> ReactDOM.render(<App />, document.getElementById("root"));
---------------------
const path = require("path");
const webpack = require("webpack");
// dev環(huán)境下的webpack配置文件她混,
module.exports = {
// 文件的入口
entry: "./src/index.js",
// 配置文件的名稱
mode: "development",
// 指定打包的規(guī)則
module: {
rules: [
{
test: /\.(js|jsx)$/,
// 不包含 node_modules 中的文件
exclude: /(node_modules|bower_components)/,
// 解析 ES6 依賴
loader: "babel-loader",
// 解析 react
options: { presets: ["@babel/env", "@babel/preset-react"] }
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
},
resolve: { extensions: ["*", ".js", ".jsx"] },
// 輸入路徑與文件烈钞,dev 不會創(chuàng)建輸入文件
output: {
path: path.resolve(__dirname, "./dist/"),
publicPath: "./dist/",
filename: "bundle.js"
},
// 指定 dev 的配置
devServer: {
contentBase: path.join(__dirname, "public/"),
port: 3000,
publicPath: "http://localhost:3000/dist/",
hotOnly: true
},
// 增加 模塊熱替換插件
plugins: [new webpack.HotModuleReplacementPlugin()]
};
發(fā)布環(huán)境: webpack.prod.js
const path = require('path');
// 包含需要忽略綁定外部模塊的節(jié)點
const nodeExternals = require('webpack-node-externals');
// 以下路徑是從項目路徑開始,非當(dāng)前文件的相對路徑
module.exports = {
mode: "production",
entry: "./src/index.js",
// 輸入路徑和文件
output: {
filename: "xndex.js",
path: path.resolve(__dirname, "./dist"),
// ES6 的 export
libraryTarget: "commonjs2"
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
loader: "babel-loader",
options: { presets: ["@babel/env", "@babel/preset-react"] }
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.cm\.styl$/,
loader: 'style-loader!css-loader?modules&camelCase&localIdentName=[local]-[hash:base64:5]!stylus-loader'
}
]
},
resolve: { extensions: ["*", ".js", ".jsx"] },
/**
* externals 配置選項提供了「從輸出的 bundle 中排除依賴」的方法产上。
* 相反棵磷,所創(chuàng)建的 bundle 依賴于那些存在于用戶環(huán)境(consumer's environment)中的依賴。
* 此功能通常對 library 開發(fā)人員來說是最有用的晋涣,然而也會有各種各樣的應(yīng)用程序用到它仪媒。
*
* 防止將某些 import 的包(package)打包到 bundle 中,
* 而是在運行時(runtime)再去從外部獲取這些擴(kuò)展依賴(external dependencies)谢鹊。
* 例如:
* externals: {
jquery: 'jQuery'
}
*/
externals: [nodeExternals()]
};
此時的項目結(jié)構(gòu)如下:
四:啟動和打包
1:在 package.json 中添加啟動命令算吩,執(zhí)行 npm start
啟動項目
"scripts": {
"start": "webpack-dev-server --config ./webpack.dev.js",
"build": "webpack --config ./webpack.prod.js"
},
2:執(zhí)行 npm run build
將項目打包,此時會在項目根目錄生成 dist 文件夾和xndex.js的文件
佃扼,正常情況下偎巢,生成的文件就可以給其他人引用。
五:組件化和引用
1:上面的步驟兼耀,其實和我們創(chuàng)建一個 react 項目是一樣的压昼,主要是為了測試我們的組件,相當(dāng)于組件的demo瘤运,我們用這個demo來調(diào)試我們的組件窍霞;但是我們的目的是將這個項目導(dǎo)出,所以需要修改一下 index.js
中的內(nèi)容拯坟,導(dǎo)出這個組件
index.js 修改如下但金,注意這里的導(dǎo)出方式為 export 并且修改了名稱,引用的時候需要 import { Test1App } 需要加上括號哦郁季。
import App from "./App.js";
export {
App as Test1App
}
1:我們在使用react
組件化的時候冷溃,其實不需要打包钱磅;只要使用 babel
將src下面的文件進(jìn)行ES6轉(zhuǎn)ES5編譯輸出,我們添加另一個編譯命令babel src --out-dir lib --copy-files
(同時將不需要編譯的文件copy出來)似枕,執(zhí)行 npm run compile
盖淡,然后在根目錄下會生成 lib 文件夾
添加啟動命令
package.json 添加內(nèi)容如下:
"scripts": {
"start": "webpack-dev-server --config ./webpack.dev.js",
"build": "webpack --config ./webpack.prod.js",
"compile": "babel src --out-dir lib --copy-files"
},
2:執(zhí)行上面的命令后,我們差不多完成了組件化菠净,只需要在 package.json
中修改 main 文件的入口即可
package.json 添加內(nèi)容如下:
"main": "./lib/index.js",
六:創(chuàng)建一個新的項目禁舷,引用組件
1:我們創(chuàng)建另一個項目,這里我采用create-react-app
這個工具鏈進(jìn)行創(chuàng)建
npx create-react-app my_firstcompent_exeple
然后在項目里引用上面的組件 "myfirstcompent": "file:../myFirstCompent#v1.0.0"
組件的名稱毅往,在組件的package.json 的name 中定義牵咙,#v1.0.0 是指定組件的版本,當(dāng)我們修改組件后攀唯,要提高組件的版本洁桌,然后在依賴中修改引用組件的版本
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1",
"myfirstcompent": "file:../myFirstCompent#v1.0.0"
},
2:執(zhí)行 cnpm install
,我們可以看到終端顯示
? All packages installed (1 packages installed from local file, used 4s(network 4s), speed 0B/s, json 0(0B), tarball 0B)
顯示我們引用了一個 本地的文件
3:在 index.js 文件中增加引用 import {Test1App} from 'myfirstcompent';
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
// import App from './App';
import {Test1App} from 'myfirstcompent';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
<React.StrictMode>
<Test1App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();