1. 程式人生 > >webpack4+react+antd從零搭建React腳手架(二)

webpack4+react+antd從零搭建React腳手架(二)

接著上文,對webpack 的配置的優化和對css,圖片的編譯。以及引入antd
專案程式碼地址react-project

優化webpack

生成的檔名新增Hash值

output: {
    filename: "js/[name].[chunkhash].js",
},

生產過程中,清理dist資料夾。安裝外掛 clean-webpack-plugin

npm install --save-dev clean-webpack-plugin
  • 修改 webpack.prod.conf.js
const CleanWebpackPlugin = require('clean-webpack-plugin');
...
module.exports = merge(baseWebpackConfig, { 
	 plugins: [
	 	new CleanWebpackPlugin(['../dist'], { allowExternal: true })
	]
})

新增熱載入模組

yarn add --save-dev webpack-dev-server

在build中新增webpack.dev.conf.js檔案

const path = require('path');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf.js');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');


module.exports = merge(baseWebpackConfig, {
  mode: 'development',
  output: {
    filename: "js/[name].[hash:16].js",
  },
  // 源錯誤檢查
  devtool: 'inline-source-map',
  plugins: [
    // 處理html
    new HtmlWebpackPlugin({
      template: 'public/index.html',
      inject: 'body',
      minify: {
        html5: true
      },
      hash: false
    }),
    // 熱更新
    new webpack.HotModuleReplacementPlugin(),
  ],
  // 熱更新
  devServer: {
    port: '3000',
    contentBase: path.join(__dirname, '../public'),
    compress: true,
    historyApiFallback: true,
    hot: true, //開啟
    https: false,
    noInfo: true,
    open: true,
    proxy: {}
  }
});

在package.json scripts屬性新增內容

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "build": "webpack --config build/webpack.prod.conf.js",
  },

npm run dev
自動開啟瀏覽器開啟入口頁面實時更新

對 css less sass 檔案進行處理

  • 安裝依賴
npm install extract-text-webpack-plugin
npm install style-loader css-loader postcss-loader autoprefixer --save-dev
npm install less sass less-loader sass-loader stylus-loader node-sass --save-dev
  • webpack.base.conf.js 檔案修改
// webpack.base.conf.js
 {
        test: /\.css$/,
        use: ['style-loader', 'css-loader',],
      },
{
   test:/\.less$/,
   use: [
         {  loader: "style-loader"  },
         {  loader: "css-loader" },
         {
            loader: "postcss-loader",//自動加字首
            options: {
                   plugins:[
                          require('autoprefixer')({
                              browsers:['last 5 version']
                          })
                  ]
            }
         },
         {  loader: "less-loader" }
     ]
},
      {
        test: /\.scss$/,
        use: [
          { loader: "style-loader" },
          {
            loader: "css-loader",
          },
          { loader: "sass-loader" },
          {
            loader: "postcss-loader",
            options: {
              plugins: [
                require('autoprefixer')({
                  browsers: ['last 5 version']
                })
              ]
            }
          }
        ]
      },

對圖片和字型進行編譯

  • 安裝依賴
npm i file-loader url-loader --save-dev

webpack.base.conf.js 檔案修改

{
        test: /\.(png|jpg|gif)$/,
        use: [{
          loader: 'url-loader',
          options: {
            // outputPath:'../',//輸出**資料夾
            publicPath: '/',
            name: "images/[name].[ext]",
            limit: 1000  //是把小於1000B的檔案打成Base64的格式,寫入JS
          }
        }]
      },
      {
        test: /\.(woff|svg|eot|woff2|tff)$/,
        use: 'url-loader',
        exclude: /node_modules/
        // exclude忽略/node_modules/的資料夾
      }

然後可以在index.js引入一個圖片還有css檔案進行編譯試試看。

對生成的程式碼進行分析

引入依賴

yarn add webpack-bundle-analyzer -D

在/ webpack.prod.conf.js 檔案

// webpack.prod.conf.js 檔案
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
...

  plugins: [
   
    // 分析哪些檔案體積過大
    new BundleAnalyzerPlugin(),

  ],

引入antd

這裡開始出現天坑了,巨坑了
mdzz的。

安裝antd
現在從 yarn 或 npm 安裝並引入 antd。

yarn add antd

修改index.js,引入 antd 的按鈕元件。

import React from "react";
import ReactDom from "react-dom";
import { Button, Switch } from 'antd';

import styles from './index.less'
import Pic from './g.jpg'


const Div = document.createElement("div");
Div.setAttribute("id", "root")
document.body.appendChild(Div)
ReactDom.render(
  <div>
    <h1 className={styles.green}>hello, world!333</h1>
    <img src={Pic}></img>
    <Button type="primary">Primary</Button>
    <Switch defaultChecked />
  </div>,
  document.getElementById("root")
);

這時候100%的沒有效果。
官方文件在引入antd的css時候,給了兩種方案。文件連結

  1. 一種是在index.css,在檔案頂部引入 antd/dist/antd.css
  2. 另一種是按需載入元件程式碼和樣式。

這裡使用了一個新的外掛babel-plugin-import

yarn add babel-plugin-import
{
  "presets": [
    "react",
    "env"
  ],
  "plugins": [
    [
      "import",
      {
        "libraryName": "antd",
        "libraryDirectory": "lib",
        "style": true
      }
    ]
  ]
}

babel-plugin-import的使用方法babel-plugin-import
這時候,文件已經解釋完畢。

結果發現完全按照文件寫的結果還是不行!!!

谷歌半天的坑才知道還需要的webpack配置的js裡面進行配置一下。
我這裡是將antd的樣式改寫為less,引入的。所以如果需要覆蓋樣式的話。一定要將字尾改為.less
直接上配置
less配置了兩遍,一遍還不行,別問我為什麼。我也不知道。

 {
        test: /\.css$/,
        use: ['style-loader', 'css-loader',],
      },
      {
        test: /\.less$/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader' },
          {
            loader: "postcss-loader",
            options: {
              plugins: [
                require('autoprefixer')({
                  browsers: ['last 5 version']
                })
              ]
            }
          },
          // javascriptEnabled: true  ------  在less裡面可以使用JavaScript表示式
          { loader: 'less-loader', options: { javascriptEnabled: true } },
        ],
        // 切記這個地方一定要引入antd,文件上沒有寫入但是一定要因引進去,切記切記
        include: [/antd/],
      },
      {
        test: /\.less$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: true,
              sourceMap: true,
              localIdentName: '[name]__[local]--[hash:base64:5]',
            },
          },
          {
            loader: "postcss-loader",
            options: {
              plugins: [
                require('autoprefixer')({
                  browsers: ['last 5 version']
                })
              ]
            }
          },
          { loader: 'less-loader', options: { javascriptEnabled: true } },
        ],
        exclude: [/antd/],
      },

至此大工告成。