webpack4老项目路由太多太慢,用浏览器自动驱动动态引入路由

97 阅读1分钟

入了个新公司,项目都是webpack4的项目,启动跟热更新十分的慢,热更新慢十分难受,网上搜罗一些信息,编写出一下代码以便极速编译

const fs = require("fs")
const path = require("path")

class RouteLazyLoadPlugin {
    constructor(options) {
        this.options = options;
    }

    apply(compiler) {
        const scriptText = `<script type="text/javascript">
            function changeRouteCallback(){
                window.fetch("/refresh?hash="+window.location.hash.substring(1))
            }
            let originReplaceState = history.replaceState
            history.replaceState = function(){
                let r = originReplaceState.apply(history, arguments)
                changeRouteCallback()
                return r
            }
            let originPushState = history.pushState
            history.pushState = function(){
                let r = originPushState.apply(history, arguments)
                changeRouteCallback()
                return r
            }
            window.addEventListener(
            "hashchange",
            function () {
                changeRouteCallback()
            });
        </script>`;
        compiler.hooks.compilation.tap('RouteLazyLoadPlugin', compilation => {
            console.log("The compiler is starting a new compilation...");
            compilation.hooks.htmlWebpackPluginAfterHtmlProcessing.tapAsync('HtmlAfterProcessingPlugin', (htmlPluginData, callback) => {
                htmlPluginData.html = htmlPluginData.html.replace(/<\/body>/i, `${scriptText}</body>`);
                callback(null, htmlPluginData);
            });
        });
    }
}

module.exports = {
    RouteLazyLoadPlugin,
    handleDevServerBefore(app) {
        let lastRefreshPath = '' // 可以改为数组,10个之内缓存
        app.get('/refresh', (req) => {
            const p = path.resolve(__dirname, "../src/config/dyRoute.js")
            const item = req.query.hash
            if(lastRefreshPath === item) {
                console.log("路径相同,不用刷新");
                return
            }
            let output = `export function devRoutePath() {}`
            if (item !== "/" && item !== "/home" && item !== "/login") {
                console.log(`获取${item}路径组件`);
                output = `// 此文件是开发时自动生成的,最好不要修改
export function devRoutePath(item) {
    if(process.env.NODE_ENV === 'production') {
        return () => import(\`@/views\${item.path}.vue\`)
    }
    const devRouteData = {
        "${item}": () => import(\`@/views${item}.vue\`)
    }
    return devRouteData[item.path]
}
`
lastRefreshPath = item
                fs.writeFileSync(p, output, "utf-8")
            }
        });
    }
};

原理就是动态引入时不要引入所有组件,只引入对应的组件。