webpack output.publicPath 如何动态配置地址

webpack 中 output.publicPath 如何动态配置地址

例:

有一个通过 require.ensure 加载的 chunk.js

当其在开发环境时 output.publicPath 不需要配置也能成功调用,这是因为环境地址资源目录在同一地址下,而output.publicPath默认指向环境地址,所以暂且不说;

而当其需要把 chunk.js 上传到测试地址时,这就发生了变化。

由于测试地址(www.test.com)资源目录(static.test.com)不在同一个路径下,chunk.js 也就抛 404 了,这就需要在上传时修改 config.js,才能保证资源文件的成功访问。

output.publicPath = 'static.test.com'

这本没有什么,只是当需要将 chunk.js 部署到生产环境时,其环境地址(www.prod.com)资源目录(static.prod.com)又发生了改变,如果保证chunk.js能正常访问,又需要修改config.js:

output.publicPath = 'static.prod.com'

而在实际开发时也非常操蛋,在需要部署测试时需要做对应修改,在需要部署生产时又需要做对应修改;

有没有什么方法能够动态设置或者让 output.publicPath 自动匹配 开发测试生产这些环境,而不是去做多次修改,多次上传;

是我打开方式不对?还是有什么副本没打?求大神赐教...

阅读 16.6k
4 个回答

自己搞定了,由于网上大多的答案都讲的一知半解,我来细说一下流程,帮助遇到相同问题的朋友;

由于提问比较久远,首先啰嗦一下,回顾一下问题,在实际工作中,我们往往会涉及到 本地环境测试环境预发布生产环境 等等诸如此类的一些乱七八糟的开发环境。

而想要高大上的使用 require.ensure 就必须解决按需加载在不同环境下配置成不同地址的需求,而大家都了解按需加载文件需要 publicPath 配置的地址,而这个地址在打包的时候就已经决定了。

那么问题来了!

总不能换一个环境打包提交一次吧,别说你懵逼,运维也受不了!

索性,找到了一个关键性的参数 __webpack_public_path__ 惰性加载模块;

其实网上也有不少人提过这个参数,但是令人愤恨的是,大都没讲明白;

下面我们就这一参数以实例的方式进行讲解:

搞定这一功能需分三步,webpack配置文件模板js 都需要配合修改:

webpack配置文件:

    output:{
        publicPath: '' //这一项必须删除,不能写空
        //很多人使用 __webpack_public_path__ 没有效果就是因为 publicPath保留了下来
        //没有设置过这一项的,请忽略
    }

模板文件:

    <meta name="AppPublic" content="http://cdn.static.com">
    // AppPublic 是用于 js 能够捕捉到 meta 元素
    // content 就是资源文件地址了,可以写入 PHP 的路径

JS文件:

    //获取 meta 元素
    var $path = document.querySelector('meta[name="AppPublic"]');
    //如果该 meta 元素存在,则获取其 content 的路径
    //如果该 meta 元素不存在,则为本地路径
    __webpack_public_path__ = $path
                ? $path.getAttribute('content')+'/app/js/'
                : '/';
    //从该参数的使用上可以了解到,上面 meta 元素,本地可以不添加
    //js获取不到执行本地环境路径,js获取成功则配置具体环境路径
    
    // __webpack_public_path__ 的添加位置需要注意
    // 最好是添加在调用按需加载的文件里

完成后,打包 webpack ; 动态配置路径成功!

感谢 meepo 提供的灵感

开发环境和生产环境的分开,用process.ene.NODE_ENV自动判断环境取publicPath

    publicPath: process.env.NODE_ENV === 'production'
    ? config.build.assetsPublicPath
    : config.dev.assetsPublicPath
module.exports = function(webpackonfigs) {
    if(webpackConfigs.options && webpackonfigs.options.debug != true) {
        webpackConfigs.output.publicPath = 'https://xxx.cdn.com/';
    }
}
1 篇内容引用
推荐问题
宣传栏