@tuax/plugin-ssr
Version:
tua 的 vue 直出插件
135 lines (123 loc) • 4.11 kB
JavaScript
const path = require('path');
const fs = require('fs');
let ssrType = 'vue';
/**
* 设置ssr类型
* eg:
* ```js
* const ssr = require('@tuax/plugin-ssr')
* ssr('vue').pages(...);
* ```
* @param {string} type 目前支持 vue react
*/
module.exports = function (type) {
ssrType = type;
return module.exports;
};
module.exports.clientConf = function (chainedConfig, env, config) {
const webpack = require('webpack');
chainedConfig
.plugin('defineClientEnv')
.use(webpack.DefinePlugin, [{
'process.env': {
NODE_ENV: env === 'DEBUG' ? '"development"' : '"production"',
SERVER_SIDE: false,
},
}]);
};
module.exports.serverConf = function (chainedConfig, env, config) {
const webpack = require('webpack');
chainedConfig.node
.set('__filename', false)
.set('__dirname', false)
.set('global', true);
// externals中配置的库,不会被打包进server.js中,会使用publish项目中安装的相应依赖
chainedConfig.externals([
function (context, request, callback) {
// 下列包中有直接动态依赖相对目录的实现,打包后路径查找出错,需要externals
const list = new Set(['@tencent/tlogger', '@tencent/rainbow-node-sdk', '@tencent/polaris']);
if (list.has(request)) {
return callback(null, `commonjs ${request}`);
}
callback();
},
]);
chainedConfig
.plugin('defineSsrEnv')
.use(webpack.DefinePlugin, [{
'process.env': {
NODE_ENV: env === 'DEBUG' ? '"development"' : '"production"',
SERVER_SIDE: env === 'TOSERVER', // 线上、预发布、测试服务器环境
},
}]);
};
/**
* ssr入口生成模板
* @param {string} pageName
* @param {string} appPath
* @returns
*/
const template = (pageName, appPath) => {
const unifyPath = pathStr => pathStr.split(path.sep)
.join('/');
const buildDir = path.dirname(require.resolve('@tencent/tua-ssr-server'));
return `
const init = require('${unifyPath(path.resolve(buildDir, `./${ssrType}`))}')
const app = require('${unifyPath(appPath)}')
module.exports = (server, htmlTemplate) => {
init({
router: server.router,
htmlTemplate
}, {
name: '${pageName}',
createApp: app.createApp,
})
}`;
};
/*
* @params {array} ssr 直出页面列表pageList
*/
module.exports.pages = (ssr, params, getDefaultPages) => {
// 通过老的方式设置框架类型
if (!!ssr.type) {
throw new Error('不再支持在type中设置类型, 请使用 require(\'@tuax/plugin-ssr\')(${type}) 的方式设置类型');
}
// 如果ssr变量是对象
const isObject = typeof ssr === 'object' && !Array.isArray(ssr);
const pageList = isObject ? ssr.pageList : ssr;
const defaultPages = getDefaultPages(params);
Object.keys(defaultPages)
.filter(name => pageList.includes(name))
.forEach((name) => {
const relAppPath = `${path.dirname(defaultPages[name].entry)}/app`;
const serverEntryPath = `${defaultPages[name].entry}.server`; // 自动查找 ${entry}.server.js
if (fs.existsSync(`${serverEntryPath}.js`)) {
defaultPages[name].serverEntry = serverEntryPath;
} else {
const appPath = path.resolve(process.cwd(), relAppPath);
defaultPages[name].serverEntryCode = template(name, appPath);
defaultPages[name].minify = false; // 在服务端html内容中的注释不删除
}
});
return defaultPages;
};
// 处理需要在项目package.json中固定添加的一些scripts
module.exports.generate = function (options) {
const userPkg = require(require('path')
.resolve(process.cwd(), './package.json'));
if (ssrType === 'vue') {
return {
dependencies: {
...(userPkg.dependencies['vue-server-renderer'] ? {} : { 'vue-server-renderer': '2.6.14' }),
},
};
}
if (ssrType === 'react') {
return {
dependencies: {
...(userPkg.dependencies['react-router'] ? {} : { 'react-router': '^5.1.2' }),
...(userPkg.dependencies['react-router-config'] ? {} : { 'react-router-config': '^5.1.1' }),
},
};
}
};