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

本文目的實現從零搭建一個react後臺管理系統,這是第一章!搭建基本的項目。css

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

本文適合人羣:react,webpack有必定基礎前端

技術棧vue

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

廢話很少說,前方高能,正式開始嘍node

初始化項目

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

  2. 安裝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打包入口,以下圖:

QQ截圖20190810105541.png

QQ截圖20190810105621.png

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

下邊開始正式配置webpack啦~

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

webpack的基礎配置

一、項目根目錄建立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目錄

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插件,上邊已經安裝過

一、添加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

二、豐富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等工具進行"翻譯一下"

一、安裝,配置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"。

二、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.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-router5+react-loadable+mobx系列文章

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

二、react+webpack4搭建前端項目(二)react全家桶的使用

三、react+webpack4搭建前端項目(三)打包優化

相關文章
相關標籤/搜索