本文目的實現從零搭建一個react後臺管理系統,這是第一章!搭建基本的項目。css
本篇主要講述一步步搭建react
項目雛形(不使用create-react-app
,umi
等),包括配置基本webpack,再到react+webpack
配置整合,到完成項目的啓動和打包(不包含react
相關技術棧的使用和webpack
的打包優化)。這些東西我還會在以後更新新的文章來詳細講解react
相關技術棧(全家桶react+react-router+axios+antd+mobx
)的使用以及webpack
打包優化html
本文適合人羣:react,webpack有必定基礎前端
技術棧vue
react+react-router+axios+antd+mobx
後邊在寫項目中會使用,本文不涉及webpack4.x
廢話很少說,前方高能,正式開始嘍node
建立package.json,執行npm init
一路按enter鍵就搞定了react
安裝webpack基本包(本文采用webpack4.x,注意了啊,各位同窗)webpack
npm install --D webpack webpack-dev-server webpack-cli
複製代碼
webpack4.x
必須安裝webapck-cli
,這是一個注意事項ios
新建src/index.js
,添加代碼以下nginx
console.log("hello world")
複製代碼
在package.json
執行腳本添加"build":"webpack"
es6
在終端執行npm run build
,能夠看到在根目錄生成了dist/main.js的打包文件,這是webpack4.x打包默認找src/index.js打包入口,以下圖:
上邊已經說明webpack在本項目中能夠成功構建打包js文件了,其它用法請查看官方文檔!
下邊開始正式配置webpack啦~
一步步從最基本的配置出發,到建立不一樣環境webpack配置文件來區分不一樣環境,在到詳細配置不一樣環境的webpack;最後配置react的開發和打包環境
一、項目根目錄建立build目錄,建立webpack.config.js
基本配置
const path = require("path");
function resolve(dir) {
return path.resolve(__dirname, dir)
}
module.exports = {
// 指定構建環境
mode:"development",
// 入口
entry: {
app: "./src/index"
},
// 出口
output: {
path : resolve("../dist"),
filename: "js/[name].[hash].js",
publicPath: "/" // 打包後的資源的訪問路徑前綴
},
// 模塊
module:{
},
// 插件
plugins:[
],
// 開發環境本地啓動的服務配置
devServer: {
}
}
複製代碼
上邊每一項配置都有註釋,有什麼不懂的基本配置能夠看官方文檔
二、編寫,配置html模板,實現html模板的打包,安裝插件
npm install -D html-webpack-plugin
複製代碼
在根目錄建立index.html
模板,代碼很簡單
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>mydemo</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
複製代碼
三、在webpack.config.js的plugins添加
new HtmlWebpackPlugin({
filename: resolve('./../dist/index.html'), // html模板的生成路徑
template: 'index.html',//html模板
inject: true, // true:默認值,script標籤位於html文件的 body 底部
hash: true, // 在打包的資源插入html會加上hash
// html 文件進行壓縮
minify: {
removeComments: true, //去註釋
collapseWhitespace: true, //壓縮空格
removeAttributeQuotes: true //去除屬性引用
}
})
複製代碼
四、修改package.json
的build命令爲指定配置文件構建打包"build": "webpack --config build/webpack.config.js"
,而後再次執行npm run build
,這時候已經能夠把html模板和打包後的資源插入到html模板,最後打包進dist目錄
爲了區分開發環境和生產環境,下面咱們一步一步抽取wenpack公共配置 分別建立 utils.js ,webpack.base.config.js , webpack.dev.config.js , webpack.prod.config.js
在抽取webpack配置過程當中,須要使用webpack-merge插件,安裝方式
npm install -D webpack-merge
複製代碼
這個插件是用來合併webpack配置的,能夠對不一樣文件的webpack配置合併成一個完整的webpack配置。具體用法請看下面
utils.js是webpack配置用的工具方法
const path = require("path")
exports.resolve = function (dir) {
return path.resolve(__dirname, dir)
}
複製代碼
webpack.base.config.js 是webpack在不一樣環境的公共配置
const utils = require("./utils")
module.exports = {
// 入口
entry: {
app: "./src/index"
},
// 出口
output: {
path : utils.resolve("../dist"),
filename: "js/[name].[hash].js",
publicPath: "/" // 打包後的資源的訪問路徑前綴
},
// 模塊
module:{
},
}
複製代碼
webpack.dev.config.js 是項目開發環境的配置
const webpackMerge = require("webpack-merge");
const baseWebpackConfig = require("./webpack.base.config")
const utils = require("./utils")
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = webpackMerge(baseWebpackConfig,{
// 指定構建環境
mode:"development",
// 插件
plugins:[
new HtmlWebpackPlugin({
filename: utils.resolve('./../dist/index.html'), // html模板的生成路徑
template: 'index.html',//html模板
inject: true, // true:默認值,script標籤位於html文件的 body 底部
})
],
// 開發環境本地啓動的服務配置
devServer: {
}
});
複製代碼
webpack.prod.config.js 是項目生產環境環境的配置
const webpackMerge = require("webpack-merge");
const baseWebpackConfig = require("./webpack.base.config")
const utils = require("./utils")
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = webpackMerge(baseWebpackConfig,{
// 指定構建環境
mode:"production",
// 插件
plugins:[
new HtmlWebpackPlugin({
filename: utils.resolve('./../dist/index.html'), // html模板的生成路徑
template: 'index.html',//html模板
inject: true, // true:默認值,script標籤位於html文件的 body 底部
hash: true, // 在打包的資源插入html會加上hash
// html 文件進行壓縮
minify: {
removeComments: true, //去註釋
collapseWhitespace: true, //壓縮空格
removeAttributeQuotes: true //去除屬性引用
}
})
],
})
複製代碼
在修改package.json
的build命令:
"build": "webpack --config build/webpack.prod.config.js"
複製代碼
而後再次執行npm run build
,一切正常!
配置生產環境webpack.dev.config.js其實上面步驟已經完成,但還比較簡單,後邊會結合react的打包進行整合
開發環境須要咱們使用webpack-dev-server插件,上邊已經安裝過
一、添加package.json命令,用webpack-dev-server啓動服務
"dev": "webpack-dev-server",
複製代碼
執行npm run dev
,如今已經能夠正常啓動一個服務了,默認端口8080,服務的根目錄是項目的根目錄
可是這種方式沒有指定配置文件啓動,因此還需改爲指定配置文件啓動
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.config.js",
複製代碼
在次執行npm run dev
,你會看到配置的資源和html模板已經被webpack構建
這時候瀏覽器打開http://localhost:8080,看到src/index.js的內容執行了
二、豐富webpack-dev-server配置,在webpack.dev.config.js的devServer屬性下添加開發環境啓 動服務的配置
// 開發環境本地啓動的服務配置
devServer: {
historyApiFallback: true, // 當找不到路徑的時候,默認加載index.html文件
hot: true,
contentBase: false, // 告訴服務器從哪裏提供內容。只有在你想要提供靜態文件時才須要
compress: true, // 一切服務都啓用gzip 壓縮:
port: "8081", // 指定段靠譜
publicPath: "/", // 訪問資源加前綴
proxy: {
// 接口請求代理
},
}
複製代碼
執行npm run dev
,啓動服務,這時候配置文件已經把服務端口改成8081
,輸入http://localhost:8081,修改src/index.js,此時能夠看到瀏覽器會熱更新,到此開發環境的配置基本完成,若是須要了解更多請查看文檔
react
npm install -S react react-dom
複製代碼
修改src/index.js文件,使用react,react-dom
把react
的spa
頁面插入到html
模板id
爲app
的盒子當中,從新運行項目npm run dev
,不出意外你驚訝的發現報錯了。這是此時webpack還不能編譯構建react的代碼,那麼接下來咱們進行支持react的打包構建
咱們都知道,要想把react的代碼使用webpack編譯構建成瀏覽器能夠運行的代碼,須要使用babel等工具進行"翻譯一下"
一、安裝,配置babel(babel7.x)
npm install -D @babel/core @babel/preset-env @babel/preset-react
npm install -D @babel/plugin-transform-runtime @babel/runtime @babel/runtime-corejs2
複製代碼
@babel/core babel
babel的核心庫@babel/preset-env
把es6,es7語法轉換成es5。bebel7以上的版本只用這一個預設包就能夠實現語法的轉換,已經廢棄了preset-stage-0,preset-stage-1,preset-stage-2
等這些包。可是這個包還不能轉換es6,es7的一些新特性好比Array.includes()
,這就須要咱們使用@babel/plugin-transform-runtime
了@babel/preset-react
把react語法轉換爲es5@babel/plugin-transform-runtime
支持一些es6,es7的新語法那麼安裝完了,咱們須要添加babel的配置了,在項目目錄建立.babelrc
,配置內容以下
{
"presets": [
["@babel/preset-env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"@babel/preset-react"
],
"plugins": [
["@babel/plugin-transform-runtime",{
"corejs": 2, // polyfill 須要使用@babel/runtime-corejs2
"useBuildIns":"usage", //按需引入,即便用什麼新特性打包什麼新特性, 能夠減少打包的體積
}]
]
}
複製代碼
上邊有兩個地方講解一下,在配置plugin-transform-runtime
時候,須要安裝依賴@babel/runtime
,還添加了特殊配置"corejs": 2
,"useBuildIns":"usage"
,爲何添加這些配置呢?
"corejs": 2
: @babel/runtime + @babel/plugin-transform-runtime 在 babel7 下只包含 helper function(即 Babel 進行處理時須要的幫助函數), 若是想實現 polyfill , 須要使用@babel/runtime-corejs2。"useBuildIns":"usage"
: 要實現真正的按需引入,即便用什麼新特性打包什麼新特性,能夠使用實驗性的 useBuildIns:"usage"。二、webpack4.x配置編譯打包規則
安裝loaders
babel-loader
使用babel進行編譯項目npm install -D babel-loader
複製代碼
style-loader,css-loader
編譯css文件npm install -D style-loader css-loader
複製代碼
url-loader file-loader
引入文件路徑(圖片,字體)npm install -D url-loader file-loader
複製代碼
less-loader
識別less
文件npm install -D less less-loader
複製代碼
安裝完這些包以後,咱們須要在webpacl.base.config.js添加打包編譯構建規則 在module下添加rules屬性
rules:[
{
test: /\.(js|jsx)$/,//一個匹配loaders所處理的文件的拓展名的正則表達式,這裏用來匹配js和jsx文件(必須)
exclude: /node_modules/,//屏蔽不須要處理的文件(文件夾)(可選)
loader: 'babel-loader',//loader的名稱(必須)
},
{
test: /\.css$/,
use:[
{
loader: 'style-loader', // 建立 <style></style>
},
{
loader: 'css-loader', // 轉換css
}
]
},
{
test: /\.less$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
{
loader: 'less-loader', // 編譯 Less -> CSS
},
],
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000, // url-loader 包含file-loader,這裏不用file-loader, 小於10000B的圖片base64的方式引入,大於10000B的圖片以路徑的方式導入
name: 'static/img/[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000, // 小於10000B的圖片base64的方式引入,大於10000B的圖片以路徑的方式導入
name: 'static/fonts/[name].[hash:7].[ext]'
}
}
]
複製代碼
這些配置相比vue框架的配置少了對vue文件的編譯構建配置。你會發如今vue項目vue-loader,vue-style-loader,vue-template-compiler
這三個插件是必不可少的,這是用來處理vue文件的包
繼續在webpack.base.config.js添加
resolve: {
extensions: ['.js', '.json'], // 解析擴展。(當咱們經過路導入文件,找不到改文件時,會嘗試加入這些後綴繼續尋找文件)
alias: {
'@': path.join(__dirname, '..', "src") // 在項目中使用@符號代替src路徑,導入文件路徑更方便
}
}
複製代碼
三、編寫頁面,運行項目,測試打包
新建assets/img目錄,把圖片放在該目錄下
在src
下新建home/index.js
,home/test.css
,home/test.less
home/index.js內容:
import React from 'react'
import "./test.less"
import "./test.css"
import buyImg from "@/assets/img/icon_buy_task.png"
import testImg from "@/assets/img/bg_store.png"
export default class Home extends React.Component {
render(){
return (
<div className="test test2">
<p>hello world</p>
<img src={buyImg} alt="" />
<img src={testImg} alt="" style={{width:360,height:60}}/>
</div>
)
}
}
複製代碼
test.css
.test2 {
font-size: 32px;
}
複製代碼
test.less
.test {
background: rebeccapurple;
}
複製代碼
而後修改src/index.js入口文件
import React from 'react'
import ReactDom from 'react-dom'
import HomePage from "./home"
class App extends React.Component {
render(){
return (
<div style={{color:"#333"}} className="test test2">
<HomePage />
</div>
)
}
}
ReactDom.render(<App/>,document.getElementById("app"))
複製代碼
這時候項目的節本雛形已經造成:
而後咱們運行和打包項目 先執行npm run dev
,服務正常啓動,瀏覽器打開http://localhost:8081 頁面效果:
最後打包執行npm run build
,打包成功
此時,比較大的圖片和js的bundle都已經正常打包,那麼咱們怎麼測試打包的代碼正常呢?這裏我推薦一個插件(不用把靜態包部署到nginx服務器就能夠運行)http-server
npm install -g http-server
複製代碼
全局安裝http-server包,安裝成功以後,cd dist
目錄,執行http-server
命令
這時候啓動了一個服務,默認開啓8080端口
以下圖:
這時候打開瀏覽器,輸入http://localhost:8081,發現頁面正常訪問!
就這樣一個基本的項目雛形有了!
下一篇: react技術棧的使用
react+webpack4+react-router5+react-loadable+mobx
系列文章
一、react+webpack4搭建前端項目(一)基礎項目搭建