從零配置webpack(react+less+typescript+mobx)


本文目標

從零搭建出一套支持react+less+typescript+mobx的webpack配置

 

最簡化webpack配置

 

首頁要初始化yarn和安裝webpack的依賴

 

yarn init -y
yarn add webpack webpack-cli -D

 

 

根目錄下新建webpack.config.js文件,內容如下

 

const path = require('path');

module.exports = {
    mode: 'development',
    // 入口 這里應用程序開始執行
    entry: path.resolve(__dirname, 'src/index.tsx'),
    // 出口 
    output: {
        // 輸出文件的目標路徑
        path: path.resolve(__dirname, 'dist'),
        // 輸出的文件名
        filename: 'bundle.js',
        // 輸出解析文件的目錄。靜態資源最終訪問路徑 = output.publicPath + 資源loader或插件等配置路徑
        publicPath: '/'
    }
}

 

 

使用命令進行打包

 

webpack --mode production

 

 

另外亦可以將命令配置到 package.json 中的 scripts 字段

 

"scripts": {
    "build": "webpack --mode production"
},

 

 

執行命令 yarn build 即可打包

 

使用模版html

 

html-webpack-plugin 插件 可以指定template模板文件,將會在output目錄下,生成html文件,並引入打包后的js.

 

安裝依賴

 

yarn add html-webpack-plugin -D

 

 

在webpack.config.js增加plugins配置

 

const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    //...other code
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, 'src/index.html')
        })
    ]
}

 

 

html-webpack-plugin 插件 還支持title、minify、filename等其他參數

 

配置webpack-dev-server

 

webpack-dev-server提供了一個簡單的Web服務器和實時熱更新的能力,有助於開發。

 

安裝依賴

 

yarn add webpack-dev-server -D

 

 

在webpack.config.js中增加devServer配置

 

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    //...other code
    devServer: {
        hot: true,
        port: 3000,
        open: true,
        contentBase: path.resolve(__dirname, 'dist'),
        // 開發模式下寫/就行啦
        publicPath: '/',
    }
}

 

 

在 package.json 的 scripts 字段中增加 start模式 

 

"scripts": {
    "start": "webpack-dev-server --mode development",
    "build": "webpack --mode production"
},

 

 

這樣我們就可以通過yarn start來啟動服務啦

 

官網devServer

 

鏈接Webpack中publicPath詳解

 

支持加載css文件

 

通過使用不同的 style-loader 和 css-loader, 可以將 css 文件轉換成js    文件類型。

 

安裝依賴

 

yarn add style-loader css-loader -D

 

 

在webpack.config.js中增加loader配置

 

module.exports = {
    //other code
    module: {
        rules: [
            {
                test: /\.css/,
                use: ['style-loader', 'css-loader'],
                exclude: /node_modules/,
                include: path.resolve(__dirname, 'src')
            }
        ]
    }
}

 

 

loader 可以配置以下參數:

  • test: 匹配處理文件的擴展名的正則表達式
  • use: loader名稱
  • include/exclude: 手動指定必須處理的文件夾或屏蔽不需要處理的文件夾
  • query: 為loader提供額外的設置選項

 

支持圖片加載

 

需要引入兩個loader

  • file-loader: 解決CSS等文件中的引入圖片路徑問題
  • url-loader: 當圖片小於limit的時候會把圖片Base64編碼,大於limit參數的時候還是使用file-loader進行拷貝

 

如果希望圖片存放在單獨的目錄下,那么需要指定outputPath

 

安裝依賴

 

yarn add url-loader file-loader -D

 

 

在 webpack.config.js 中增加 loader 的配置(增加在 module.rules 的數組中)。

 

module.exports = {
    //other code
    module: {
        rules: [
            {
                test: /\.(gif|jpg|png|bmp|eot|woff|woff2|ttf|svg)/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            limit: 8192,
                            outputPath: 'images'
                        }
                    }
                ]
            }
        ]
    }
} 

 

 

支持編譯less

 

很多前端都喜歡寫less,所以支持less也是需要的。(sass配置方法基本相同)

 

安裝依賴

 

yarn add less less-loader -D

 

 

在 webpack.config.js 中增加 loader 的配置(module.rules 數組中)。

 

module.exports = {
    //other code
    module: {
        rules: [
            {
                test: /\.less/,
                use: ['style-loader', 'css-loader', 'less-loader'],
                exclude: /node_modules/,
                include: path.resolve(__dirname, 'src')
            },
        ]
    }
}        

 

 

支持轉義 ES6/ES7/JSX(react)

 

安裝ES6/ES7/JSX 轉義需要 Babel 的依賴,支持裝飾器。

 

yarn add @babel/core babel-loader @babel/preset-env @babel/preset-react @babel/plugin-proposal-decorators @babel/plugin-proposal-object-rest-spread -D

 

 

在 webpack.config.js 中增加 loader 的配置(module.rules 數組中)。

 

module.exports = {
    //other code
    module: {
        rules: [
            {
                test: /\.jsx?$/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: ['@babel/preset-env', '@babel/react'],
                            plugins: [
                                [
                                  "@babel/plugin-proposal-decorators", 
                                  { "legacy": true }
                                ]
                            ]
                        }
                    }
                ],
                include: path.resolve(__dirname, 'src'),
                exclude: /node_modules/
            },
        ]
    }
}

 

 

壓縮JS文件

 

安裝依賴

 

yarn add uglifyjs-webpack-plugin -D

 

 

在 webpack.config.js 中增加 optimization 的配置

 

const UglifyWebpackPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
    //other code
    optimization: {
        minimizer: [
            new UglifyWebpackPlugin({
                parallel: 4
            })
        ]
    }
}

 

 

分離出CSS

 

因為CSS的下載和JS可以並行,當一個HTML文件很大的時候,可以把CSS單獨提取出來加載

 

安裝依賴

 

yarn add mini-css-extract-plugin -D

 

 

在 webpack.config.js 中增加 plugins 的配置,並且將 'style-loader' 修改為 { loader: MiniCssExtractPlugin.loader}。CSS打包在單獨目錄,那么配置filename。

 

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    //other code
    module: {
        rules: [
            {
                test: /\.css/,
                use: [{ loader: MiniCssExtractPlugin.loader}, 'css-loader'],
                exclude: /node_modules/,
                include: path.resolve(__dirname, 'src')
            },
            {
                test: /\.less/,
                use: [{ loader: MiniCssExtractPlugin.loader }, 'css-loader', 'less-loader'],
                exclude: /node_modules/,
                include: path.resolve(__dirname, 'src')
            },
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'css/[name].css'
        })
    ]
}

 

 

壓縮CSS文件

 

安裝依賴

 

yarn add optimize-css-assets-webpack-plugin -D

 

 

在 webpack.config.js 中的 optimization 中增加配置

 

const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = {
    //other code
    optimization: {
        minimizer: [
            new OptimizeCssAssetsWebpackPlugin()
        ]
    }
}

 

 

支持react和mobx

 

安裝react依賴

 

yarn add react react-dom 

 

 

安裝mobx依賴

 

yarn add mobx mobx-react

 

 

支持typescript

 

安裝依賴

 

yarn add typescript awesome-typescript-loader -D

 

 

安裝react的類型依賴(否則會有命名空間和.d.ts相關報錯)

 

yarn add @types/react @types/react-dom

 

 

在 webpack.config.js 中增加 loader 的配置(module.rules 數組中)。

 

module.exports = {
    //other code
    module: {
        rules: [
             {
                test: /\.(tsx|ts)?$/,
                loader: "awesome-typescript-loader",
                exclude: /node_modules/,
                include: path.resolve(__dirname, 'src')
            }
        ]
    }
}

 

 

在根目錄下添加tsconfig.json

 

{
  "compilerOptions": {
    "baseUrl": ".",
    "outDir": "build/dist",
    "module": "esnext",
    "target": "es5",
    "lib": ["es6", "dom"],
    "sourceMap": true,
    "allowJs": true,
    "jsx": "react",
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "rootDir": "./",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": false,
    "importHelpers": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": false,
    "allowSyntheticDefaultImports": true
  },
  "exclude": [
    "node_modules",
    "build",
    "scripts",
    "acceptance-tests",
    "webpack",
    "jest",
    "src/setupTests.ts"
  ]
}

 

 

在根目錄下添加tslint.json

 

{
  "extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"],
  "rules": {
    "no-empty-interface":false,
    "no-empty-block":false,
    "no-unused-expression":false,
    "object-literal-sort-keys":false,
    "no-empty":false,
    "semicolon": [false, "always"],
    "no-default-export": false,
    "member-access": true,
    "ordered-imports": false,
    "import-sources-order": "any",
    "named-imports-order": "any",
    "interface-over-type-literal":false,
    "jsx-no-lambda":false,
    "variable-name": [
      true,
      "ban-keywords",
      "check-format",
      "allow-leading-underscore",
      "allow-trailing-underscore",
      "allow-pascal-case",
      "allow-snake-case"
    ],
    "no-console": false,
    "no-angle-bracket-type-assertion": false,
    "jsx-no-string-ref":false,
    "prefer-for-of":false,
    "member-ordering":false,
    "only-arrow-functions":false,
    "object-literal-shorthand":false
  },
  "linterOptions": {
    "exclude": [
      "config/**/*.js",
      "node_modules/**/*.ts",
      "coverage/lcov-report/*.js"
    ]
  },
  "strict": false
}

 

 

打包前先清空輸出目錄

 

安裝依賴

 

yarn add clean-webpack-plugin -D

 

 

在 webpack.config.js 中增加 plugins 的配置

 

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

module.exports = {
    //other code
    plugins: [
        new CleanWebpackPlugin()
    ]
}

 

 

( 注意3.0版本的clean-webpack-plugin有大改動,需要通過構造函數取出CleanWebpackPlugin再用 )

 

至此,webpack配置已經基本能滿足react+less+typescript+mobx開發需求。

 

完整webpack.config.js和package.json文件

 

webpack.config.js文件

 

const path = require('path');
// 打包html的插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 壓縮JS的插件
const UglifyWebpackPlugin = require('uglifyjs-webpack-plugin');
// 分離css文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// 打包前先清空輸出目錄
const {CleanWebpackPlugin} = require('clean-webpack-plugin');

module.exports = {
    mode: 'development',
    // 入口 這里應用程序開始執行
    entry: path.resolve(__dirname, 'src/index.tsx'),
    // 出口
    output: {
        // 所有輸出文件的目標路徑
        path: path.resolve(__dirname, 'dist'),
        // 輸出的文件名
        filename: 'bundle.js',
        // 輸出解析文件的目錄,url 相對於 HTML 頁面, publicPath 上線時配置的是cdn的地址。
        // 靜態資源最終訪問路徑 = output.publicPath + 資源loader或插件等配置路徑
        publicPath: './'
    },
    devServer: {
        hot: true,
        port: 3000,
        open: true,
        contentBase: path.resolve(__dirname, 'dist'),
        publicPath: '/',
        // stats: 'none'
    },
    module: {
        rules: [
            /*
            * 支持css
            * 通過使用不同的 style-loader 和 css-loader, 可以將 css 文件轉換成JS文件類型。
            * */
            {
                test: /\.css/,
                // use: ['style-loader', 'css-loader'],
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    'css-loader'
                ],
                exclude: /node_modules/,
                include: path.resolve(__dirname, 'src')
            },
            /*
            * 支持編譯less和sass
            * */
            {
                test: /.less/,
                // use: ['style-loader', 'css-loader', 'less-loader'],
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    'css-loader',
                    'less-loader'
                ],
                exclude: /node_modules/,
                include: path.resolve(__dirname, 'src')
            },
            /*
            * 支持加載圖片
            * file-loader: 解決CSS等文件中的引入圖片路徑問題
            * url-loader: 當圖片小於limit的時候會把圖片Base64編碼,大於limit參數的時候還是使用file-loader進行拷貝
            * */
            {
                test: /\.(gif|jpg|png|bmp|eot|woff|woff2|ttf|svg)/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            limit: 1,
                            outputPath: 'images'
                        }
                    }
                ]
            },
            /*
            * 支持轉義 ES6/ES7/JSX  ,支持react
            * ES6/ES7/JSX 轉義需要 Babel 的依賴,支持裝飾器。
            * */
            {
                test: /\.jsx?$/,
                use: [
                    {
                        loader: "babel-loader",
                        options: {
                            presets: ['@babel/preset-env', '@babel/react'],
                            plugins: [
                                [
                                    "@babel/plugin-proposal-decorators",
                                    // "@babel/plugin-proposal-class-properties",
                                    {
                                        "legacy": true
                                    }
                                ]
                            ]
                        }
                    }
                ],
                exclude: /node_modules/,
                include: path.resolve(__dirname, 'src')
            },
            /*
           * 支持轉義 支持typescript
           * ES6/ES7/JSX 轉義需要 Babel 的依賴,支持裝飾器。
           * */
            {
                test: /\.(tsx|ts)?$/,
                loader: "awesome-typescript-loader",
                exclude: /node_modules/,
                include: path.resolve(__dirname, 'src')
            }
        ]
    },
    optimization: {
        minimizer: [
            new UglifyWebpackPlugin({
                parallel: 4
            })
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, 'public/index.html')
        }),
        new MiniCssExtractPlugin({
            filename:'css/[name].css'
        }),
        new CleanWebpackPlugin()
    ]
};

 

 

package.json文件

 

{
  "name": "webpack_cli",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "start": "webpack-dev-server --mode development",
    "build": "webpack --mode production"
  },
  "devDependencies": {
    "@babel/core": "^7.5.5",
    "@babel/plugin-proposal-decorators": "^7.4.4",
    "@babel/plugin-proposal-object-rest-spread": "^7.5.5",
    "@babel/preset-env": "^7.5.5",
    "@babel/preset-react": "^7.0.0",
    "@types/react": "^16.9.2",
    "@types/react-dom": "^16.8.5",
    "awesome-typescript-loader": "^5.2.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.10.1",
    "less-loader": "^5.0.0",
    "mini-css-extract-plugin": "^0.8.0",
    "optimize-css-assets-webpack-plugin": "^5.0.3",
    "style-loader": "^1.0.0",
    "typescript": "^3.5.3",
    "uglifyjs-webpack-plugin": "^2.2.0",
    "url-loader": "^2.1.0",
    "webpack": "^4.39.2",
    "webpack-cli": "^3.3.7",
    "webpack-dev-server": "^3.8.0"
  },
  "dependencies": {
    "mobx": "^5.13.0",
    "mobx-react": "^6.1.3",
    "react": "^16.9.0",
    "react-dom": "^16.9.0"
  }
}

 

 

學習更多webpack配置請進入webpack官網 webpack官網鏈接

 

本文配置將持續升級優化


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM