記一次webpack+typescript+react的優化過程

說在前頭

項目採用的是react + webpack + typescript + tslint的技術棧,優化以後速度有了大幅度的提升。javascript

優化以前的webpack配置

module.exports = {
        ...,
        module: {
            rules : [
                {
                    test: /\.tsx?$/,
                    use: [
                        {
                            loader: 'awesome-typescript-loader',
                            options: {
                                configFileName: './tsconfig.json',
                                useCache: true,
                            }
                        }
                    ],
                },
                {
                    test: /\.tsx?$/,
                    enforce: 'pre',
                    loader: 'tslint-loader',
                    options: {
                        configFile: path.resolve(__dirname, './tslint.json'),
                        emitErrors: true,
                        failOnHint: true
                    },
                },
            ]
        }
    }
複製代碼

爲何想要棄用 awesome-typescript-loader呢?是由於每當文件改動時,該loader都會從新去轉譯和類型檢查,項目慢慢大了,特別影響開發速度,而且會有類型檢查遺漏的狀況發生。java

@babel/preset-typescript方案,直接移除了TypeScript,轉爲JS,這使得它的編譯速度飛快。node

優化以後的webpack配置

{
                test: /\.(jsx?|tsx?)$/,
                use: ['thread-loader',  // 採用thread-loader多進程編譯源文件
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: ['@babel/preset-typescript'],
                            plugins: [
                                ["@babel/plugin-proposal-decorators", {
                                    legacy: true }],
                                ['@babel/plugin-transform-typescript', {
                                    allExtensions: true,
                                    isTSX: true,
                                    allowNamespaces: true }],
                            ]
                        },
                    }
                ],
            },
            {
                test: /\.tsx?$/,
                use: ['eslint-loader'], 
                // 因爲去除了ts,故採用eslint來進行代碼檢測,同時添加ForkTsCheckerWebpackPlugin和ForkTsCheckerNotifierWebpackPlugin兩個plugin單獨開個進程來作lint
            },
複製代碼

babel.config.js(babel配置文件)react

module.exports = function (api) {
    api.cache(true);

    const presets = [
        "@babel/preset-typescript",
        "@babel/preset-react",
        "@babel/preset-env",
        "mobx"
    ];
    const plugins = [
        "react-hot-loader/babel",
        "@babel/proposal-object-rest-spread",
        ["@babel/plugin-transform-runtime"],
        ["@babel/plugin-transform-modules-commonjs", { "strictMode": true }],
        ["@babel/plugin-proposal-decorators", { "legacy": true }],
        ["@babel/plugin-proposal-class-properties", { "loose": true }]
    ];

    return {
        presets,
        plugins
    };
}
複製代碼

.eslintrc.js (eslint配置文件)webpack

module.exports = {
    parser:  '@typescript-eslint/parser',  //定義ESLint的解析器
    extends: [
        'plugin:react/recommended',
        'plugin:@typescript-eslint/recommended'
    ], //定義文件繼承的子規範
    plugins: ['@typescript-eslint'],       //定義了該eslint文件所依賴的插件
    env:{                                  //指定代碼的運行環境
        browser: true,
        node: true,
        commonjs: true,
        es6: true
    },
    settings: {                            //自動發現React的版本,從而進行規範react代碼
        "react": {
            "pragma": "React",
            "version": "detect"
        }
    },
    parserOptions: {                       //指定ESLint能夠解析JSX語法
        "ecmaVersion": 2019,
        "sourceType": 'module',
        "ecmaFeatures":{
            jsx:true
        }
    },
    rules: {
    }
}
複製代碼

須要特別指出的是,採用babel-loader以後,咱們不能直接使用webpack-dev-server自帶的hot模塊,而是應該經過react-hot-loader來處理熱更新的部分。es6

新增的package.jsonweb

devDependencies: {
        "@babel/core": "^7.9.0",
        "@babel/plugin-proposal-class-properties": "^7.8.3",
        "@babel/plugin-proposal-decorators": "^7.8.3",
        "@babel/plugin-proposal-object-rest-spread": "^7.9.5",
        "@babel/plugin-transform-modules-commonjs": "^7.9.0",
        "@babel/plugin-transform-runtime": "^7.9.0",
        "@babel/plugin-transform-strict-mode": "^7.8.3", // 用來設置打包後js是否爲嚴格模式
        "@babel/preset-env": "^7.9.5",
        "@babel/preset-react": "^7.9.4",
        "@babel/preset-typescript": "^7.9.0",
        "@typescript-eslint/eslint-plugin": "2.27.0",
        "@typescript-eslint/parser": "2.27.0",
        "babel-loader": "^8.1.0",
        "babel-plugin-transform-class-properties": "^6.24.1",
        "babel-plugin-transform-decorators-legacy": "^1.3.5",
        "babel-preset-mobx": "^2.0.0", // 項目裏用到了mobx
        "eslint": "^6.8.0",
        "eslint-loader": "^4.0.0",
        "eslint-plugin-react": "^7.19.0",
        "react-hot-loader": "^4.12.20",
    },
    dependencies: {
        "@babel/runtime": "^7.9.2", // 構建時須要
    }
複製代碼
相關文章
相關標籤/搜索