react+webpack4.x搭建前端項(xiàng)目(四)配置抽取和區(qū)分環(huán)境

前言

前三章介紹了項(xiàng)目搭建和webpack打包優(yōu)化。
1、react+webpack4搭建前端項(xiàng)目(一)基礎(chǔ)項(xiàng)目搭建
2、react+webpack4搭建前端項(xiàng)目(二)react全家桶的使用
3、react+webpack4搭建前端項(xiàng)目(三)打包優(yōu)化

這里小編推薦一個(gè)福利,更多精彩內(nèi)容請(qǐng)點(diǎn)擊鏈接,點(diǎn)擊這里

接下來(lái),我們接著上一篇文章react+webpack4搭建前端項(xiàng)目(三)打包優(yōu)化進(jìn)行webpack配置的提取和區(qū)分(開發(fā),測(cè)試,生產(chǎn))環(huán)境和編寫腳本進(jìn)行打包

簡(jiǎn)化項(xiàng)目代碼

把src下的代碼刪除,新建index.js

import React from 'react'
import ReactDom from 'react-dom'
import "./app.less"

class App extends React.Component {
    render(){
        return (
            <div class="test">
                hello react-apps-template
            </div>
        )
    }
}

ReactDom.render(<App/>,document.getElementById("app"))

app.less

.test {
    color: purple;
    font-size: 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

執(zhí)行npm run dev, npm run build測(cè)試正常

區(qū)分不同環(huán)境

webpack4.x之后,webpack內(nèi)置了process.env.NODE_ENV這個(gè)環(huán)境變量而且只有兩個(gè)值(development開發(fā),production生產(chǎn)),但是我們項(xiàng)目一般都會(huì)有開發(fā)開環(huán)境,測(cè)試環(huán)境,預(yù)發(fā)布環(huán)境,生產(chǎn)環(huán)境等等。

所以這里我們需要在package.json添加打包測(cè)試環(huán)境的執(zhí)行命令

"build-test": "cross-env NODE_ENV=test webpack --progress --config build/webpack.prod.config.js"

然后我們通過(guò)webpack之內(nèi)的插件在webpack配置中添加另外一個(gè)全局環(huán)境變量(只要不和NODE_ENV重名就行)

我們?cè)?code>webpack.base.config.js中的plugins中添加如下代碼

new Webpack.DefinePlugin({
    'process.env': {
        APP_ENV:JSON.stringify(process.env.NODE_ENV)
    },
}),

這樣我么就為項(xiàng)目注入了全局變量APP_ENV,我們可以在app.js中打印APP_ENV的值測(cè)試一下

console.log(process.env.APP_ENV)

接著我們分別執(zhí)行npm run devnpm run build-test,npm run build查看打印的值。
那么我們?cè)趺纯创虬蟮捻?xiàng)目呢,我們之前介紹過(guò)http-server工具,在打包成功后

cd dist
http-server

根據(jù)提示打開瀏覽器,打開控制臺(tái)查看就可以

webpack配置的提取

我們?cè)?code>utils.js中編寫公用的cssLoaders方法來(lái)處理cssless

function cssLoaders(options){
    options = options || {};
    const cssLoader = { 
        loader: 'css-loader',  // 轉(zhuǎn)換css
        options:{
            sourceMap: options.sourceMap
        }
    };

    function generateLoaders(loader,loaderOptions){
        const loaders = [cssLoader,'postcss-loader'];
        if(loader){
            loaders.push({
                loader: loader+"-loader",
                options:Object.assign({},loaderOptions , {
                    sourceMap: options.sourceMap
                })
            })
        }
        if(options.extract){
            return [
                {
                    loader:MiniCssExtractPlugin.loader,
                    options:{
                        hmr: process.env.NODE_ENV != 'development',  // 開發(fā)環(huán)境熱更新 ,然而不起作用
                        reloadAll:true,
                    }
                }
            ].concat(loaders);
        }else{
           return ['style-loader'].concat(loaders)
        }
    }

    const object = {
        css: generateLoaders(),
        less: generateLoaders("less")
    }
    const output = [];
    for(let key in object){
        const loader = object[key];
        output.push({
            test:new RegExp('\\.' + key + '$'),
            use:loader
        })
    }
    return output;
}

然后我們把webapck.base.config.js處理css,less相關(guān)的loader刪除,分別在webpack.dev.config.js,webpack.prod.config.js中添加處理cssloader

webpack.dev.config.js如下

module:{
    rules:utils.cssLoaders()
},

webpack.prod.config.js如下

module:{
    rules:utils.cssLoaders({extract:true,sourceMap:true})
},

測(cè)試環(huán)境不需要壓縮css。生產(chǎn)環(huán)境需要對(duì)css文件進(jìn)行壓縮和輸出sourceMap

接下來(lái)把webpack.base.config.js中的output修改成不再文件名后添加后綴配置

output: {
    path : utils.resolve("../dist"),
    filename: utils.assetsPath("js/[name].js") ,
    publicPath: "/" // 打包后的資源的訪問(wèn)路徑前綴
},

webpack.prod.config.js中添加output

output: {
    path : utils.resolve("../dist"),
    filename: utils.assetsPath("js/[name].[hash].js") ,
    chunkFilename: utils.assetsPath("js/[name].[chunkhash].js"),
    publicPath: "/" // 打包后的資源的訪問(wèn)路徑前綴
},

這樣的話,開發(fā)環(huán)境js文件就不會(huì)帶hash后綴嘍

然后把webpack.base.config.js下的plugins中的

new MiniCssExtractPlugin({
    filename: utils.assetsPath('css/[name].[hash].css'),
    chunkFilename: utils.assetsPath('css/[id].[chunkhash].css'),
})

移到webpack.prod.config.js,這樣開發(fā)環(huán)境css也不會(huì)帶hash后綴嘍

這里的文件開發(fā)環(huán)境就不需要去hash后綴名嘍,如果需要的話,那也需要分區(qū)開發(fā)環(huán)境和打包環(huán)境

編寫build.js打包

我們可以編寫一個(gè)js腳本,然后用在node命令執(zhí)行這個(gè)腳本,在這個(gè)腳本中進(jìn)行webpack打包。
我們需要利用webpack提供的方法webpack(config,handler),
該方法的第一個(gè)參數(shù)是webpack的配置對(duì)象,第二個(gè)是webpack打包執(zhí)行結(jié)果的回調(diào)

新建build/build.js文件
安裝ora,chalk

npm install -D ora chalk

ora是用于在shell終端顯示加載中的效果,類似于前端頁(yè)面的loading效果
chalk是用于在shell終端輸出帶顏色顏色文本的插件

這兩款插件的具體使用方法請(qǐng)看官網(wǎng)文檔

編寫build.js

const webpack = require("webpack")
const ora = require("ora");
const chalk = require("chalk")
const WebpackConfig = require("./webpack.prod.config")


// 啟動(dòng)動(dòng)畫
const spinner = ora("build....")
spinner.start()


// 開始構(gòu)建
webpack(WebpackConfig,function(err,stats){
    // 停止動(dòng)畫
    spinner.stop()
    // 打包出錯(cuò),拋出異常信息
    if (err) throw err
    // 控制臺(tái)輸出打包成功信息
    process.stdout.write(stats.toString({
      colors: true,
      modules: false,
      children: false,
      chunks: false,
      chunkModules: false
    }) + '\n\n')

    console.log(chalk.cyan('  Build complete.\n'))
    console.log(chalk.yellow(
      '  Tip: built files are meant to be served over an HTTP server.\n' +
      '  Opening index.html over file:// won\'t work.\n'
    ))
    process.exit(); // 終止終端進(jìn)程
})

然后修改package.json的打包命令

"build-test": "cross-env NODE_ENV=test node build/build.js",
"build": "cross-env NODE_ENV=production node build/build.js"

分別執(zhí)行測(cè)試,如下圖:

QQ截圖20191213125331.png

打包結(jié)果如下圖

QQ截圖20191213125345.png

源碼請(qǐng)看release0.0.1版本源碼0.0.1

下一篇:多頁(yè)面配置 react+webpack4.x搭建前端項(xiàng)目之多頁(yè)面配置

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容