【前端】Vue2全家桶案例《看漫画》之七、webpack插件开发——自动替换服务器API-URL

转载请注明出处:http://www.cnblogs.com/shamoyuu/p/vue_vux_app_7.html

项目github地址:https://github.com/shamoyuu/vue-vux-iconan

想来这个项目也做了一月了,期间部署了好几次,也经常在本地联调后台接口,所以服务器地址经常换来换去。

有一次部署的时候还把localhost给部署上去了,不得不部署第二次。

我们这一章就来解决这个问题,根据命令行参数,打包自动替换不同的服务器地址,不用再修改api.js了。

首先我们修改tools/api.js,为我们的服务器地址设置一个占位符

let apiUrl = "<<<service>>>";
let picServer = "<<<pic-service>>>";

console.info("apiUrl", apiUrl);
console.info("picServer", picServer);

因为对js的压缩不会压缩字符串,所以我们就可以通过替换占位符来做到我们上面提到的功能。

然后我们新建一个server.json文件,来保存我们各个平台,各个环境下的服务器地址

{
    "webapp": {
        "environments": {
            "dev": {
                "service": "http://localhost:18080/iconan",
                "pic-service": "http://iconan.bj.bcebos.com"
            },
            "test": {
                "service": "http://meleong.duapp.com/iconan",
                "pic-service": "http://iconan.bj.bcebos.com"
            },
            "production": {
                "service": "/iconan",
                "pic-service": "http://iconan.bj.bcebos.com"
            }
        }
    },
    "mobile": {
        "environments": {
            "dev": {
                "service": "http://localhost:18080/iconan",
                "pic-service": "http://iconan.bj.bcebos.com"
            },
            "test": {
                "service": "http://meleong.duapp.com/iconan",
                "pic-service": "http://iconan.bj.bcebos.com"
            },
            "production": {
                "service": "http://meleong.duapp.com/iconan",
                "pic-service": "http://iconan.bj.bcebos.com"
            }
        }
    }
}

这样就可以一目了然,想修改也特别方便。

然后我们修改gulpfile.js,先来通过指令的参数获取到我们想要的服务器地址

const serverConfig = require(process.cwd() + "/server.json");
global.SERVERS = serverConfig[args.t]["environments"][args.e];

然后我们来替换,如果是用gulp的管道的话,可以这么写,修改webpack.build文件

"webpack.build": (done) => {
    let spinner = ora("正在打包,请稍后...");
    spinner.start();
    webpack(webpackConfig, (err, stats) => {
        spinner.stop();
        if (err) throw err;
        process.stdout.write(stats.toString({
            colors: true,
            modules: false,
            children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
            chunks: false,
            chunkModules: false
        }) + "\n\n");

        if (stats.hasErrors()) {
            console.log(chalk.red("  构建出错。\n"));
            process.exit(1);
        }

        // let stream = gulp.src(["dist/**/*"]);
        // let servers = serverConfig[args.t]["environments"][args.e];
        // for (let key in servers) {
        //     stream = stream.pipe(replace("<<<" + key + ">>>", servers[key]))
        // }
        // stream.pipe(gulp.dest("dist"))
        //     .on('end', function () {
        //         console.log(chalk.cyan("  构建完成。\n"));
        //         done();
        //     });

        done();
    });
},

就是图里注释掉的那段。但是这样在开发环境下不可用,因为我们是用webpack配置的开发环境,如果你用的是gulp,可以这么做。

所以我们给webpack写一个插件来实现这个功能。

首先我们修改dev任务

const webpackDevConfig = require(process.cwd() + "/build/webpack.dev.conf");


"dev": () => {
    let devCompiler = webpack(webpackDevConfig);

    new WebpackDevServer(devCompiler)
        .listen(webpackDevConfig.devServer.port, webpackDevConfig.devServer.host, function (err) {
            if (err) throw new gutil.PluginError("webpack-dev-server", err);
            console.log(chalk.cyan("  服务已启动\n"));
        });
}

然后修改webpack.dev.conf最后的exports = devWebpackConfig,不要返回那个Promise。

然后我们写一个插件,新建build/plugin/servers-replace-webpack-plugin.js文件

function ServersReplaceWebpackPlugin(options) {
    this.options = options;
}

ServersReplaceWebpackPlugin.prototype.apply = function (compiler) {
    let that = this;

    compiler.plugin('emit', function (compilation, callback) {
        // 检查所有编译好的资源文件,替换所有需要替换的地方
        for (var filename in compilation.assets) {
            if (filename.endsWith(".js")) {
                console.info("filename =", filename);
                let newFile = compilation.assets[filename].source().toString();

                let servers = that.options;
                for (let key in servers) {
                    newFile = newFile.replace("<<<" + key + ">>>", servers[key]);
                }

                compilation.assets[filename] = {
                    source: function () {
                        return newFile;
                    },
                    size: function () {
                        return newFile.length;
                    }
                };
            }
        }

        callback();
    });
};

module.exports = ServersReplaceWebpackPlugin;

然后分别为webpack.dev.conf和webpack.prod.conf添加这个插件。

它的参数就是在gulpfile.js里声明的 global.SERVERS

此系列到此结束。

完结,散花~