Webpack4+Babel7+React16+Less簡單配置筆記

Webpack4+Babel7+React16+Less簡單配置筆記

1、項目初始化

新建一個項目react-initcss

mkdir react-init
cd react-init
複製代碼

初始化html

yarn init -y
# 或
npm init -y
複製代碼

2、安裝Webpack

webpack4的安裝須要安裝兩個,一個是webpack,另外就是webpack-clihtml5

yarn add webpack webpack-cli -D
# 或
npm i webpack webpack-cli -D
複製代碼

3、創建webpack配置文件

在項目根目錄下面建立config目錄,並在該目錄裏面建3個配置文件,分別是:node

webpack.base.conf.js —— 共有配置react

webpack.dev.conf.js —— 開發環境配置webpack

webpack.prod.conf.js —— 生產環境配置web

由於使用了公共的配置項,因此爲了可以使用公共項,須要引入另一個庫,安裝以下:npm

yarn add webpack-merge -D
# 或
npm i webpack-merge -D
複製代碼

在webpack.base.conf.js裏面寫入:json

const path = require('path');
const DIST_PATH = path.resolve(__dirname, '../dist');
const APP_PATH = path.resolve(__dirname, '../src');

module.exports = {
  entry: {
    app: APP_PATH+'/index.js'
  },
  output: {
    filename: "js/[name].[chunkhash].js",
    path: DIST_PATH
  },
  resolve: {
    extensions: [".js", ".jsx", ".less"],
    alias: {
      "@": APP_PATH
    }
  },
}
複製代碼

在webpack.dev.conf.js裏面寫入:瀏覽器

const path = require("path");
const merge = require("webpack-merge");
const baseWebpackConfig = require("./webpack.base.conf");

module.exports = merge(baseWebpackConfig, {
  mode: "development",
  output: {
    filename: "js/[name].[hash:16].js"
  },
  devtool: "inline-source-map",
});
複製代碼

在webpack.prod.conf.js裏面寫入:

const merge = require("webpack-merge");
const baseWebpackConfig = require("./webpack.base.conf");

module.exports = merge(baseWebpackConfig, {
  mode: "production",
});
複製代碼

在根目錄下面建立src目錄,而後建立index.js文件,做爲整個項目的入口文件,建立App.jsx文件,做爲react項目的根組件;

在根目錄下面建立public目錄,而後建立index.html文件,做爲整個單頁項目的模板文件;

index.html內容以下:

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <!-- <title><%= htmlWebpackPlugin.options.title %></title> -->
    <title>React-Init</title>
</head>
<body>
    <div id="root"></div>
</body>
</html>
複製代碼

在package.json裏面,添加命令行腳本:

"scripts": {
  "build": "webpack --config config/webpack.prod.conf.js"
 }
複製代碼

4、安裝React

yarn add react react-dom
# 或
npm i react react-dom -S
複製代碼

修改src/App.jsx文件以下:

import React, { Component } from "react";

class App extends Component {
  render() {
    return (
      <h1>Hello React</h1>
    );
  }
}

export default App;
複製代碼

修改src/index.js文件以下:

import React from "react";
import ReactDom from "react-dom";

import App from "./App";

ReactDom.render(<App />, document.getElementById("root")); 複製代碼

5、安裝Babel

爲了使ES6的模塊化被支持以及可以轉爲瀏覽器識別的ES5代碼,和JSX格式解析,必須引入對應的babel和babel插件,安裝以下:

yarn add babel-loader @babel/core @babel/preset-env @babel/preset-react -D
# 或
npm i babel-loader @babel/core @babel/preset-env @babel/preset-react -D
複製代碼

配置babel:

在webpack.base.conf.js裏面

module.exports = {
  ...
  resolve: {
    extensions: [".js", ".jsx", ".less"],
    alias: {
      "@": APP_PATH
    }
  },
  // 如下是添加的內容
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        use: 'babel-loader',
        include: APP_PATH
      },
    ]
  }
}
複製代碼

而後在根目錄新建.babelrc文件,內容以下:

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}
複製代碼

6、添加Html模板

安裝html-webpack-plugin插件:

yarn add html-webpack-plugin -D
# 或
npm i html-webpack-plugin -D
複製代碼

這個能夠將生成的JS文件自動加載到html的script標籤內去,能夠自定義html模板,具體看其在npm網站上的文檔。

給webpack.prod.conf.js增長配置內容以下

...
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = merge(baseWebpackConfig, {
  mode: "production",
  plugins: [
    new HtmlWebpackPlugin({
      template: "public/index.html",
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
      }
    })
  ]
});
複製代碼

此時,能夠進行build了,運行

yarn build
# 或
npm run build
複製代碼

若是沒有報錯,且根目錄下生成dist目錄,則表示以前的配置基本上正確了

webpack優化

生產過程當中,可使用clean-webpack-plugin對dist文件夾先進行清理:

yarn add clean-webpack-plugin -D
複製代碼

而後在webpack.prod.conf.js裏面增長以下內容:

...
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
...
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: "public/index.html",
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
      }
    })
  ]
...
複製代碼

7、添加熱加載開發環境

yarn add webpack-dev-server -D
複製代碼

在webpack.dev.conf.js裏面添加:

...
const HtmlWebpackPlugin = require("html-webpack-plugin");
const webpack = require("webpack");

module.exports = merge(baseWebpackConfig, {
  ...
  plugins: [
    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": {
  "build": "webpack --config config/webpack.prod.conf.js",
  "dev": "webpack-dev-server --inline --progress --config config/webpack.dev.conf.js"
}
複製代碼

執行

yarn dev
# 或
npm run dev
複製代碼

便可在打開的瀏覽器裏面進行訪問,地址爲localhost:3000

8、對CSS和Less處理

使用webpack咱們能夠在js裏面導入css或less文件,可是必須使用相應的loader才能進行處理。

yarn add css-loader mini-css-extract-plugin less less-loader postcss-loader autoprefixer -D
複製代碼

在webpack.base.conf.js裏面添加

...
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
...
module.exports = {
  ...
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        use: "babel-loader",
        include: APP_PATH
      },
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              modules: true  // 使支持css modules
            }
          }
        ]
      },
      {
        test: /\.less$/,
        exclude: /node_modules/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: "css-loader",
            options: {
              modules: true
            }
          },
          {
            loader: "postcss-loader",
            options: {
              plugins: [require("autoprefixer")()]
            }
          },
          {
            loader: "less-loader",
            options: {
              modifyVars: {
                // 自定義的主題內容寫在這裏
              }
            }
          }
        ]
      },
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/[name].[hash].css",
      ignoreOrder: false
    })
  ]
};
複製代碼

爲了使autoprefixer生效,須要在package.json裏面添加以下內容:

"browserslist": [
  "last 4 version",
  "> 1%",
  "maintained node versions",
  "not dead"
]
複製代碼

9、對字體和圖片進行處理

安裝loader:

yarn add file-loader url-loader -D
複製代碼

在webpack.base.conf.js裏面添加:

module.exports = {
  ...
  module: {
    rules: [
      ...
      {
        test: /\.(png|jpg|gif|jpeg|bmp|webp)$/,
        use: [
          {
            loader: "url-loader",
            options: {
              publicPath: "/",
              name: "images/[name].[ext]",
              limit: 512
            }
          }
        ]
      },
      {
        test: /\.(woff|svg|eot|woff2|tff)$/,
        use: "file-loader",
        exclude: /node_modules/
      }
    ]
  },
  ...
};
複製代碼

到這裏,基本上所須要的配置都已經OK了,那麼所有的配置文件內容以下所示:

  1. webpack.base.conf.js

    const path = require("path");
    const DIST_PATH = path.resolve(__dirname, "../dist");
    const APP_PATH = path.resolve(__dirname, "../src");
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    
    module.exports = {
      entry: {
        app: APP_PATH + "/index.js"
      },
      output: {
        filename: "js/[name].[chunkhash].js",
        path: DIST_PATH
      },
      module: {
        rules: [
          {
            test: /\.jsx?$/,
            use: "babel-loader",
            include: APP_PATH
          },
          {
            test: /\.css$/,
            use: [
              MiniCssExtractPlugin.loader,
              {
                loader: "css-loader",
                options: {
                  modules: true
                }
              }
            ]
          },
          {
            test: /\.less$/,
            exclude: /node_modules/,
            use: [
              MiniCssExtractPlugin.loader,
              {
                loader: "css-loader",
                options: {
                  modules: true
                }
              },
              {
                loader: "postcss-loader",
                options: {
                  plugins: [require("autoprefixer")()]
                }
              },
              {
                loader: "less-loader",
                options: {
                  modifyVars: {
                    // 自定義的主題內容寫在這裏
                  }
                }
              }
            ]
          },
          {
            test: /\.(png|jpg|gif|jpeg|bmp|webp)$/,
            use: [
              {
                loader: "url-loader",
                options: {
                  publicPath: "/",
                  name: "images/[name].[ext]",
                  limit: 512
                }
              }
            ]
          },
          {
            test: /\.(woff|svg|eot|woff2|tff)$/,
            use: "file-loader",
            exclude: /node_modules/
          }
        ]
      },
      resolve: {
        extensions: [".js", ".jsx", ".less"],
        alias: {
          "@": APP_PATH
        }
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: "css/[name].[hash].css",
          ignoreOrder: false
        })
      ]
    };
    複製代碼
  2. webpack.dev.conf.js

    const path = require("path");
    const merge = require("webpack-merge");
    const baseWebpackConfig = require("./webpack.base.conf");
    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: [
        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: {}
      }
    });
    複製代碼
  3. webpack.prod.conf.js

    const merge = require("webpack-merge");
    const baseWebpackConfig = require("./webpack.base.conf");
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    const { CleanWebpackPlugin } = require("clean-webpack-plugin");
    
    module.exports = merge(baseWebpackConfig, {
      mode: "production",
      plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
          template: "public/index.html",
          minify: {
            removeComments: true,
            collapseWhitespace: true,
            removeAttributeQuotes: true
          }
        })
      ]
    });
    複製代碼
  4. .babelrc

    {
      "presets": ["@babel/preset-env", "@babel/preset-react"]
    }
    複製代碼
  5. package.json

    {
      "name": "react-init",
      "version": "1.0.0",
      "main": "index.js",
      "license": "MIT",
      "scripts": {
        "build": "webpack --config config/webpack.prod.conf.js",
        "dev": "webpack-dev-server --inline --progress --config config/webpack.dev.conf.js"
      },
      "devDependencies": {
        "@babel/core": "^7.5.5",
        "@babel/plugin-transform-runtime": "^7.5.5",
        "@babel/preset-env": "^7.5.5",
        "@babel/preset-react": "^7.0.0",
        "autoprefixer": "^9.6.1",
        "babel-loader": "^8.0.6",
        "clean-webpack-plugin": "^3.0.0",
        "css-loader": "^3.2.0",
        "file-loader": "^4.2.0",
        "html-webpack-plugin": "^3.2.0",
        "less": "^3.9.0",
        "less-loader": "^5.0.0",
        "mini-css-extract-plugin": "^0.8.0",
        "postcss-loader": "^3.0.0",
        "url-loader": "^2.1.0",
        "webpack": "^4.39.1",
        "webpack-cli": "^3.3.6",
        "webpack-dev-server": "^3.7.2",
        "webpack-merge": "^4.2.1"
      },
      "dependencies": {
        "react": "^16.8.6",
        "react-dom": "^16.8.6"
      },
      "browserslist": [
        "last 4 version",
        "> 1%",
        "maintained node versions",
        "not dead"
      ]
    }
    複製代碼

整個項目的目錄結構爲:

react-init
├── config
│   ├── webpack.base.conf.js
│   ├── webpack.dev.conf.js
│   └── webpack.prod.conf.js
├── public
│   └── index.html
├── src
│   ├── App.jsx
│   ├── app.less
│   ├── assets
│   │   └── 01.jpeg
│   └── index.js
├── .babelrc
├── package.json
└── yarn.lock
複製代碼
相關文章
相關標籤/搜索