react+webpack4搭建前端項目(一)

前言

react+webpack4搭建前端項目分為三個章節。鏈接如下。目的是實現從零搭建一個react后臺管理系統
1、react+webpack4搭建前端項目(一)基礎項目搭建
2、react+webpack4搭建前端項目(二)react全家桶的使用
3、react+webpack4搭建前端項目(三)打包優化
webpack配置的講解
4、react+webpack4.x搭建前端項目(四)配置抽取和區分環境
5、react+webpack4.x搭建前端項目(五)多頁面配置
6、react+webpack4.x多模塊打包配置

這是第一章,基本項目搭建

本篇主要講述一步步搭建react項目雛形(不使用create-react-appumi等),包括配置基本webpack,再到react+webpack配置整合,到完成項目的啟動和打包(不包含react相關技術棧的使用和webpack的打包優化)。這些東西我還會在之后更新新的文章來詳細講解react相關技術棧(全家桶react+react-router+axios+antd+mobx)的使用以及webpack打包優化

本文適合人群:react,webpack有一定基礎

技術棧

  • react框架:
    react+react-router+axios+antd+mobx 后邊在寫項目中會使用,本文不涉及
  • 打包構建
    webpack4.x

廢話不多說,前方高能,正式開始嘍

初始化項目

webpack安裝(webpack小試牛刀)
  1. 創建package.json,執行npm init一路按enter鍵就搞定了

  2. 安裝webpack基本包(本文采用webpack4.x,注意了啊,各位同學)

      npm install --D webpack webpack-dev-server webpack-cli
    

    webpack4.x 必須安裝webapck-cli,這是一個注意事項

新建src/index.js,添加代碼如下

console.log("hello world")

package.json執行腳本添加"build":"webpack"

在終端執行npm run build,可以看到在根目錄生成了dist/main.js的打包文件,這是webpack4.x打包默認找src/index.js打包入口,如下圖:

QQ截圖20190810105541.png
QQ截圖20190810105621.png

上邊已經說明webpack在本項目中可以成功構建打包js文件了,其它用法請查看官方文檔!

下邊開始正式配置webpack啦~

一步步從最基本的配置出發,到創建不同環境webpack配置文件來區分不同環境,在到詳細配置不同環境的webpack;最后配置react的開發和打包環境

webpack的基礎配置

1、項目根目錄創建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: {

    }
}

上邊每一項配置都有注釋,有什么不懂的基本配置可以看官方文檔

2、編寫,配置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>

3、在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         //去除屬性 標簽的 引號  例如 <p id="test" /> 輸出 <p id=test/>
    }
})

4、修改package.json的build命令為指定配置文件構建打包"build": "webpack --config build/webpack.config.js",然后再次執行npm run build,這時候已經可以把html模板和打包后的資源插入到html模板,最后打包進dist目錄

QQ截圖20190810113953.png
抽取webpack配置文件

為了區分開發環境和生產環境,下面我們一步一步抽取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.config.js

開發環境需要我們使用webpack-dev-server插件,上邊已經安裝過

1、添加package.json命令,用webpack-dev-server啟動服務

"dev": "webpack-dev-server",

執行npm run dev,現在已經可以正常啟動一個服務了,默認端口8080,服務的根目錄是項目的根目錄

QQ截圖20190810161241.png

但是這種方式沒有指定配置文件啟動,所以還需改成指定配置文件啟動

 "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.config.js",

在次執行npm run dev,你會看到配置的資源和html模板已經被webpack構建

QQ截圖20190810162214.png

這時候瀏覽器打開http://localhost:8080,看到src/index.js的內容執行了

QQ截圖20190810133343.png

2、豐富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,此時可以看到瀏覽器會熱更新,到此開發環境的配置基本完成,如果需要了解更多請查看文檔

webpack-dev-server詳細配置

引入react框架

安裝react
npm install -S react react-dom

修改src/index.js文件,使用react,react-domreactspa頁面插入到html模板idapp的盒子當中,重新運行項目npm run dev,不出意外你驚訝的發現報錯了。這是此時webpack還不能編譯構建react的代碼,那么接下來我們進行支持react的打包構建

支持react的打包構建(配置webpack)

我們都知道,要想把react的代碼使用webpack編譯構建成瀏覽器可以運行的代碼,需要使用babel等工具進行"翻譯一下"

1、安裝,配置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 babelbabel的核心庫
  • @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"。

2、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路徑,導入文件路徑更方便
    }
}

3、編寫頁面,運行項目,測試打包

新建assets/img目錄,把圖片放在該目錄下

src下新建home/index.jshome/test.csshome/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"))

這時候項目的基本雛形已經形成:

QQ截圖20190812122733.png

然后我們運行和打包項目
先執行npm run dev,服務正常啟動,瀏覽器打開http://localhost:8081
頁面效果:

QQ截圖20190812123014.png

最后打包執行npm run build,打包成功

QQ截圖20190812123144.png

此時,比較大的圖片和js的bundle都已經正常打包,那么我們怎么測試打包的代碼正常呢?這里我推薦一個插件(不用把靜態包部署到nginx服務器就可以運行)http-server

npm install -g http-server

全局安裝http-server包,安裝成功之后,cd dist目錄,執行http-server命令

這時候啟動了一個服務,默認開啟8080端口

如下圖:


QQ截圖20190812123523.png

這時候打開瀏覽器,輸入http://localhost:8081,發現頁面正常訪問!

就這樣一個基本的項目雛形有了!

下一篇: react技術棧的使用,react+webpack4搭建前端項目(二)react全家桶的使用

掃下邊的二維碼可以天天領紅包,以后點外賣什么的再也不用開會員了,從此省出一套房~
qrcode.jpg
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。