webpack自動化架構入門

夜還不夠黑丶發表於2019-12-24

目錄

  • 前言
  • webpack起步
  • 配置webpack
  • 構建本地伺服器
  • 配置HTML模板
  • 配置es6
  • 配置react、jsx
  • 配置css、less

前言

第一次打算學習自動化的時候是參照的一個老哥的文章,沒想到現在版本更新太快,那篇文章已經跑不起來了,所以我在這重新寫一篇最新版的搭建文章,懷念一下我老哥。

原文地址

webpack起步

1、初始化專案

mkdir react-cli && cd react-cli
npm init -y

複製程式碼

第一句: 生成react-cli資料夾並進入

第二句: -y 的含義:yes的意思,在init的時候省去了敲回車的步驟,生成的預設的package.json

2、安裝webpack

npm install webpack -D
複製程式碼

第一句: -D 是 --save-dev 的簡寫,是指安裝模組並儲存到 package.json 的 devDependencies中,主要在開發環境中的依賴包. 如果使用webpack 4+ 版本,還需要安裝 webpack-cli。

npm install -D webpack-cli
複製程式碼

3、建立專案解構

react-cli
|--package.json
|--/dist
   |--index.html
|--/src
   |--index.js
複製程式碼

index.html

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<body>
    <div id="root"></div>
    <script src="main.js"></script>
</body>
</html>
複製程式碼

index.js

document.querySelector('#root').innerHTML = 'inke';
複製程式碼

我們就可以使用webpack的打包功能了

node_modules/.bin/webpack src/index.js --output dist/bundle.js --mode development
複製程式碼

執行出入口配置都在命令中。

執行成功之後會發現dist資料夾下會多出一個main.js,這時可以開啟dist目錄下的html檔案,可以看到文字inke。

配置webpack

1、配置檔案。

根目錄下建立webpack.config.js

webpack.config.js

const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist')
    }
};
複製程式碼

走config配置之後再進行打包命令,這時會缺少出入口的配置。如下

node_modules/.bin/webpack --mode production
複製程式碼

一樣是dist資料夾中生成main.js,開啟index.html看到文字inke

2、配置script指令碼

package.json 新增一個 npm 指令碼

"scripts": {
    "build": "webpack --mode production"
},
複製程式碼

執行,即可進行打包

npm run build
複製程式碼

構建本地伺服器

webpack-dev-server 提供了一個簡單的 web 伺服器,並且能夠實時重新載入。

1、安裝 webpack-dev-server

npm install -D webpack-dev-server
複製程式碼

新增webpack配置。

const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist')
    },
    // 新增
    devServer: {
        contentBase: "./dist", // 本地伺服器所載入的頁面所在的目錄
        historyApiFallback: true, // 不跳轉
        inline: true, // 實時重新整理
        port: 3000, // 啟用埠
        open: true, // 自動開啟瀏覽器
    }
};
複製程式碼

與打包一樣,配置NPM scripts指令碼

"start": "webpack-dev-server --open --mode development"
複製程式碼

執行

npm run start
複製程式碼

即可看到本地啟動了3000埠,訪問

http://localhost:3000/
複製程式碼

我們又再次看到了inke文字。

啟動webpack-dev-server後,在目標資料夾中是看不到編譯後的檔案的,實時編譯後的檔案都儲存到了記憶體當中。因此使用webpack-dev-server進行開發的時候都看不到編譯後的檔案

2、啟用熱更新

先來科普一下定義,關於 WDS 熱更新,有以下幾點:

(1)WDS 不重新整理整個頁面;
(2)WDS 不輸出檔案,而放在記憶體中(沒有磁碟IO,速度更快);
(3)使用 HotModuleReplacementPlugin 外掛(webpack自帶);
複製程式碼

配置一個webpack自帶的外掛並且還要在主要js檔案裡檢查是否有module.hot

webpack.config.js

const path = require('path');
// 新增
const webpack = require('webpack');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.js',
        path: path.resolve(__dirname, 'dist')
    },
    devServer: {
        contentBase: "./dist", // 本地伺服器所載入的頁面所在的目錄
        historyApiFallback: true, // 不跳轉
        inline: true, // 實時重新整理
        port: 3000,
        open: true, // 自動開啟瀏覽器
        hot: true // 開啟熱更新-新增
    },
    // 新增
    plugins:[
        //熱更新
        new webpack.HotModuleReplacementPlugin()
    ],
};

複製程式碼

src/index.js

document.querySelector('#root').innerHTML = 'inke';

if (module.hot){
    //實現熱更新
    module.hot.accept();
}
複製程式碼

熱更新允許在執行時更新各種模組,而無需進行完全重新整理

重啟一下專案,看一下效果。動態修改inke文字,即可進行熱更新。

配置HTML模版

科普,為什麼要用HTML模板

The HtmlWebpackPlugin simplifies creation of HTML files to serve your webpack bundles. This is especially useful for webpack bundles that include a hash in the filename which changes every compilation. You can either let the plugin generate an HTML file for you, supply your own template using lodash templates, or use your own loader.

1、安裝html-webpack-plugin

npm install -D html-webpack-plugin
複製程式碼

新增webpack配置

webpack.config.js

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

module.exports = {
    entry: './src/index.js',
    output: {
        // 新增hash可以防止檔案快取,每次都會生成4位hash串
        filename: 'main.[hash:4].js',
        path: path.resolve(__dirname, 'dist')
    },
    devServer: {
        ...
    },
    plugins:[
        new webpack.HotModuleReplacementPlugin(),
        // 新增
        new HtmlWebpackPlugin({
            template: './src/index.html',
            hash: true, // 會在打包好的bundle.js後面加上hash串
        })
    ],
};

複製程式碼

我們把dist資料夾中的index.html移動到src中,當成模板使用。

清空dist,我們重新打包試試看

webpack自動化架構入門

這裡對index.html是模板生成的,剛才配置的hash已經配置上去了。

如果你進行改動,每次的hash值是不一樣的,這樣會有一個問題。dist檔案中 main.js檔案會越來越多。所以我們需要一個打包之前清空dist資料夾的一個Plugins.

2、安裝 clean-webpack-plugin

npm install -D clean-webpack-plugin
複製程式碼

配置webpack

webpack.config.js

...
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    output: {
        // 新增hash可以防止檔案快取,每次都會生成4位hash串
        filename: 'main.[hash:4].js',
        path: path.resolve(__dirname, 'dist')
    },
    devServer: {
        ...
    },
    plugins:[
        ...
        new CleanWebpackPlugin()
    ],
};

複製程式碼

這樣的話每次打包就不會多出檔案了。

編譯es6

這裡我們採用babel8的配置。

大概的配置是這個樣子

webpack 3.x | babel-loader 8.x | babel 7.x
複製程式碼

我們來具體安裝

npm install -D babel-loader@8.0.0-beta.0 @babel/core @babel/preset-env
複製程式碼

webpack.config.js

...

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'main.[hash:4].js',
        path: path.resolve(__dirname, 'dist')
    },
    // 新增babel-loader解析。
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env']
                    }
                }
            }
        ]
    },
    ...
};

複製程式碼

重啟一下專案,我們在src/index中試著寫一些es6語法。你會發現,會正常進行編譯。

配置react、jsx

安裝react 及 react-dom

npm install -D react react-dom
複製程式碼

安裝相應babel

npm install -D @babel/preset-react
複製程式碼

根目錄下建立.babelrc配置檔案

.babelrc

{
    "presets": ["@babel/preset-react"]
}
複製程式碼

這樣我們就可以引用react並且正常編譯了。

修改一下我們的業務程式碼

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
    <App />,
    document.querySelector('#root')
);

if (module.hot){
    //實現熱更新
    module.hot.accept();
}
複製程式碼

src/App.js

import React from 'react';

class App extends React.Component{
    render() {
        return (
            <div>inke</div>
        );
    }
}
export default App;

複製程式碼

重啟一下專案,我們會發現,專案正常執行,解析成功。

配置css、less

這裡想一個問題,如果react直接

import './App.css';

class App extends React.Component{
    render() {
        return (
            <div className="root">inke</div>
        );
    }
}
export default App;

複製程式碼

這樣會有什麼問題?

因為jsx的語法去掉後react元件是這個樣子的。

webpack自動化架構入門

className是js語法,如果我們直接引入css是無法直接進行裝飾的。

1、安裝css 相應loader

npm install -D css-loader style-loader url-loader
複製程式碼

分別為,css解析,style-loader 的作用是把轉碼後的css檔案插入到相應的 檔案中去,樣式內url地址解析。

修改webpack配置

module: {
    rules: [
        ...,
        {
            test:/\.(png|jpg|gif)$/,
            use:[
                "url-loader"
            ]
        },
        {
            test: /\.css$/,
            exclude: /node_modules/,
            use: [
                "style-loader",
                "css-loader"
            ]
        }
    ]
},
複製程式碼

這裡注意一點

loader的載入順序是從右往左。這裡的編譯順序是先用css-loader將css程式碼編譯,再交給style-loader插入到網頁裡面去。所以css-loader在右,style-loader在左。

然後我們啟動專案,再引入一下css檔案,就可以使用樣式了。

接下來解析less

2、安裝less-loader

npm install -D less-loader
複製程式碼

修改webpack配置

module: {
    rules: [
        ...,
        {
            test:/\.less$/,
            use:[
                "css-loader",
                "style-loader",
                "less-loader",
            ]
        }
    ]
},
複製程式碼

END

這樣我們就有了一套最基本的react自動化框架。

修改框架就如改裝車,接下來我們還需要去進行改裝。

一輛車光能跑是不夠的,還需要跑的又快又好。

下一篇,我們進行改裝。

相關文章