UNPKG

flow-vue-ssr-hook

Version:

flow-build针对vue服务端渲染的解决方案

168 lines (150 loc) 5.37 kB
const path = require("path"); const nodeExternals = require("webpack-node-externals"); let rules = require("./config/rules"); let plugin = require("./config/plugin"); module.exports = class VueSSRHook { /** * * @param {*} options */ constructor(options = {}) { let defaults = { output: "server-bundle.js", serverBundle: "server-bundle.json", clientManifest: "vue-ssr-client-manifest.json" }; this.options = Object.assign( { entry: true }, defaults, options ); } /** * * @param {*} builder */ apply(builder) { if (this.options.entry) { builder.on("entry-option", builder => { builder.set("entry", { client: path.resolve( __dirname, "./template/entry-client.js" ), server: path.resolve( __dirname, "./template/entry-server.js" ) }); }); } builder.on("base-config", base => { base.setConfig({ fallback: "vue-style-loader", clientManifest: this.options.clientManifest, serverBundle: this.options.serverBundle }); base.update("resolve.extensions", old => { old.push(".vue"); return old; }); base.update("resolve.alias", old => { return Object.assign({}, old, { "@": path.resolve(builder.get("srcDir")), vue$: "vue/dist/vue.esm.js" }); }); base.update("resolveLoader.modules", old => { old.push(path.join(__dirname, "./node_modules")); return old; }); }); builder.on("merge-plugin", base => { base.mergePlugin(plugin); }); builder.on("merge-rule", base => { base.mergeRule(rules); }); builder.on("merge-optimization", (config) => { config.mergeOptimization({ splitChunks: { cacheGroups: { vendor: { test: function(module) { // any required modules inside node_modules are extracted to vendor return ( module.resource && /\.js$/.test(module.resource) && module.resource.indexOf( path.join(process.cwd(), "./node_modules") ) === 0 && !/node_modules[\/\\]{1}flow\-vue\-ssr\-hook[\/\\]{1}template[\/\\]{1}/.test( module.resource ) && !/\.(css|less|scss|sass|styl|stylus|vue)$/.test(module.request) ); } } } } }); }); builder.on("client-config", client => { let entry = { app: builder.options.entry.client }; // if (client.env == "dev") { // entry.app = [ // "webpack-hot-middleware/client?name=client&reload=true&timeout=30000".replace( // /\/\//g, // "/" // ), // entry.app // ]; // } client.set("entry", entry); client.update("output", old => { return Object.assign({}, old, { devtoolModuleFilenameTemplate: "[absolute-resource-path]" }); }); }); builder.on("server-config", config => { config.update("externals", old => { old.push( nodeExternals({ whitelist: [ /es6-promise|\.(?!(?:js|json)$).{1,5}$/i, /\.css$/, /\?vue&type=style/ ] }) ); return old; }); config.update("output", old => { return Object.assign({}, old, { filename: this.options.output }); }); }); builder.on("ssr-done", (sharedFS, callback) => { let distPath = builder.options.build.outputPath; let bundlePath = path.resolve(distPath, this.options.serverBundle); let clientPath = path.resolve( distPath, this.options.clientManifest ); if ( sharedFS && sharedFS.existsSync(bundlePath) && sharedFS.existsSync(clientPath) ) { console.info("create or update ssr json"); callback && callback(sharedFS); } }); } };