Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Add SSR support #19

Merged
merged 1 commit into from
Sep 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@
"url": "git+https://github.com/gluons/vue-pack.git"
},
"devDependencies": {
"@types/cheerio": "^0.22.9",
"@types/jest": "^23.3.2",
"@types/node": "8",
"@types/webpack": "^4.4.11",
"@vue/server-test-utils": "^1.0.0-beta.25",
"@vue/test-utils": "^1.0.0-beta.25",
"babel-core": "^6.26.3",
"babel-jest": "^23.6.0",
"chalk": "^2.4.1",
"cheerio": "^1.0.0-rc.2",
"cross-env": "^5.2.0",
"jest": "^23.6.0",
"lerna": "^3.4.0",
Expand All @@ -33,6 +36,7 @@
"typescript": "^3.0.3",
"vue": "^2.5.17",
"vue-class-component": "^6.2.0",
"vue-server-renderer": "^2.5.17",
"vue-template-compiler": "^2.5.17"
}
}
5 changes: 5 additions & 0 deletions packages/@gluons/plugin-splitchunks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ const options = {

return splitChunks;
},
tapSSR(splitChunks) {
// Do anything with `splitChunks`

return splitChunks;
}
tapWeb(splitChunks) {
// Do anything with `splitChunks`

Expand Down
24 changes: 22 additions & 2 deletions packages/@gluons/plugin-splitchunks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,37 @@ export { TapFunction };
export interface SplitChunksPluginOptions {
/**
* A function to tap `splitChunks` in all configs
*
* @type {TapFunction}
* @memberof SplitChunksPluginOptions
*/
tapAll?: TapFunction;
/**
* A function to tap `splitChunks` in CommonJS config
*
* @type {TapFunction}
* @memberof SplitChunksPluginOptions
*/
tapCJS?: TapFunction;
/**
* A function to tap `splitChunks` in ES module config
*
* @type {TapFunction}
* @memberof SplitChunksPluginOptions
*/
tapESM?: TapFunction;
/**
* A function to tap `splitChunks` in SSR config
*
* @type {TapFunction}
* @memberof SplitChunksPluginOptions
*/
tapSSR?: TapFunction;
/**
* A function to tap `splitChunks` in web config.
*
* @type {TapFunction}
* @memberof SplitChunksPluginOptions
*/
tapWeb?: TapFunction;
}
Expand All @@ -49,10 +68,11 @@ export default function SplitChunksPlugin(options?: SplitChunksPluginOptions): P
tapSplitChunks(config, options.tapAll);
});
}
// tslint:disable:no-unused-expression

(typeof options.tapCJS === 'function') && tapSplitChunks(webpackConfigs.commonJSConfig, options.tapCJS);
(typeof options.tapESM === 'function') && tapSplitChunks(webpackConfigs.esModuleConfig, options.tapESM);
// tslint:enable:no-unused-expression
(typeof options.tapSSR === 'function') && tapSplitChunks(webpackConfigs.ssrConfig, options.tapSSR);

if (typeof options.tapWeb === 'function') {
tapSplitChunks(webpackConfigs.webUnminConfig, options.tapWeb);
tapSplitChunks(webpackConfigs.webMinConfig, options.tapWeb);
Expand Down
55 changes: 51 additions & 4 deletions packages/@gluons/plugin-splitchunks/test/splitChunks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,22 @@ const tapESM = splitChunks => Object.assign({}, splitChunks, {
}
});

const tapWeb = splitChunks => Object.assign({}, splitChunks, {
const tapSSR = splitChunks => Object.assign({}, splitChunks, {
cacheGroups: {
vendors: {
test: /vendors4/
}
}
});

const tapWeb = splitChunks => Object.assign({}, splitChunks, {
cacheGroups: {
vendors: {
test: /vendors5/
}
}
});

describe('SplitChunksPlugin', () => {
it('should change `splitChunks` in all configs', async () => {
const vuePackConfig: VuePackConfig = {
Expand Down Expand Up @@ -141,14 +149,14 @@ describe('SplitChunksPlugin', () => {
}
});

it('should change `splitChunks` in only web config', async () => {
it('should change `splitChunks` in only SSR config', async () => {
const vuePackConfig: VuePackConfig = {
entry: 'index.ts',
libraryName: 'Test',
externals: {}, // Prevent destructuring error
plugins: [
SplitChunksPlugin({
tapWeb
tapSSR
})
]
};
Expand All @@ -160,7 +168,7 @@ describe('SplitChunksPlugin', () => {

expect(config.optimization).toHaveProperty('splitChunks');

if ((i === 2) || (i === 3)) {
if (i === 2) {
expect(config.optimization.splitChunks).toMatchObject({
cacheGroups: {
vendors: {
Expand All @@ -179,4 +187,43 @@ describe('SplitChunksPlugin', () => {
}
}
});

it('should change `splitChunks` in only web config', async () => {
const vuePackConfig: VuePackConfig = {
entry: 'index.ts',
libraryName: 'Test',
externals: {}, // Prevent destructuring error
plugins: [
SplitChunksPlugin({
tapWeb
})
]
};

const configs: Configuration[] = await createConfigs(vuePackConfig);

for (let i = 0; i < configs.length; i++) { // tslint:disable-line: prefer-for-of
const config = configs[i];

expect(config.optimization).toHaveProperty('splitChunks');

if ((i === 3) || (i === 4)) {
expect(config.optimization.splitChunks).toMatchObject({
cacheGroups: {
vendors: {
test: /vendors5/
}
}
});
} else {
expect(config.optimization.splitChunks).not.toMatchObject({
cacheGroups: {
vendors: {
test: /vendors5/
}
}
});
}
}
});
});
11 changes: 4 additions & 7 deletions packages/@gluons/types/src/Configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,8 @@ export function toBaseOptions(config: Configuration): BaseOptions {
* @returns {WebOptions}
*/
export function toWebOptions(config: Configuration, minimize: boolean): WebOptions {
const webOptions: WebOptions = Object.assign(
{},
pick(config, [
const webOptions: WebOptions = {
...pick(config, [
'entry',
'libraryName',
'fileName',
Expand All @@ -154,10 +153,8 @@ export function toWebOptions(config: Configuration, minimize: boolean): WebOptio
'externals',
'sourceMap'
]),
{
minimize
}
);
minimize
};

return webOptions;
}
19 changes: 19 additions & 0 deletions packages/@gluons/types/src/WebpackChainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,37 @@
export interface WebpackChainConfigGroup {
/**
* Common JS `webpack-chain`'s config instance
*
* @type {any}
* @memberof WebpackChainConfigGroup
*/
readonly commonJSConfig: any;
/**
* ES module `webpack-chain`'s config instance
*
* @type {any}
* @memberof WebpackChainConfigGroup
*/
readonly esModuleConfig: any;
/**
* SSR (Server-Side Rendering) `webpack-chain`'s config instance
*
* @type {any}
* @memberof WebpackChainConfigGroup
*/
readonly ssrConfig: any;
/**
* Unminified web `webpack-chain`'s config instance
*
* @type {any}
* @memberof WebpackChainConfigGroup
*/
readonly webUnminConfig: any;
/**
* Minified web `webpack-chain`'s config instance
*
* @type {any}
* @memberof WebpackChainConfigGroup
*/
readonly webMinConfig: any;
}
Expand Down
34 changes: 16 additions & 18 deletions packages/@gluons/vue-pack/src/createConfigs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from '@gluons/vue-pack-types';
import { Configuration as WebpackConfiguration } from 'webpack';

import createModuleConfig, { Options as CreateModuleConfigOptions } from './lib/createModuleConfig';
import createModuleConfig from './lib/createModuleConfig';
import createWebConfig from './lib/createWebConfig';
import executeChainWebpack from './lib/executeChainWebpack';
import executePlugins from './lib/executePlugins';
Expand All @@ -16,6 +16,7 @@ const { toBaseOptions, toWebOptions } = ConfigurationMethods;
const barOptions = [
{ name: 'CommonJS', color: 'green' },
{ name: 'ES Module', color: 'magenta' },
{ name: 'Server-Side Rendering', color: 'blue' },
{ name: 'Web Unminified', color: 'cyan' },
{ name: 'Web Minified', color: 'yellow' }
];
Expand All @@ -29,23 +30,18 @@ const barOptions = [
*/
export default async function createConfigs(config: Configuration): Promise<WebpackConfiguration[]> {
const baseOptions = toBaseOptions(config);
const commonJSOptions: CreateModuleConfigOptions = Object.assign(
{},
baseOptions,
{
moduleType: 'common'
} as CreateModuleConfigOptions
);
const esModuleOptions: CreateModuleConfigOptions = Object.assign(
{},
baseOptions,
{
moduleType: 'es'
} as CreateModuleConfigOptions
);

const commonJSConfig = await createModuleConfig(commonJSOptions);
const esModuleConfig = await createModuleConfig(esModuleOptions);
const commonJSConfig = await createModuleConfig({
...baseOptions,
moduleType: 'common'
});
const esModuleConfig = await createModuleConfig({
...baseOptions,
moduleType: 'es'
});
const ssrConfig = await createModuleConfig({
...baseOptions,
moduleType: 'ssr'
});
const webUnminConfig = await createWebConfig(toWebOptions(config, false));
const webMinConfig = await createWebConfig(toWebOptions(config, true));

Expand All @@ -55,6 +51,7 @@ export default async function createConfigs(config: Configuration): Promise<Webp
const allConfigs = [
commonJSConfig,
esModuleConfig,
ssrConfig,
webUnminConfig,
webMinConfig
];
Expand All @@ -65,6 +62,7 @@ export default async function createConfigs(config: Configuration): Promise<Webp
const webpackConfigGroup: WebpackChainConfigGroup = {
commonJSConfig,
esModuleConfig,
ssrConfig,
webUnminConfig,
webMinConfig
};
Expand Down
4 changes: 1 addition & 3 deletions packages/@gluons/vue-pack/src/lib/createBaseConfig.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { BaseOptions } from '@gluons/vue-pack-types';
import Config from 'webpack-chain';

import infuseAliases from './infuseAliases';
import infuseWebpackModule from './infuser/infuseWebpackModule';
import infuseAliases from './infuser/infuseAliases';

/**
* Create base config via `webpack-chain`'s config instance.
Expand Down Expand Up @@ -40,7 +39,6 @@ export default async function createBaseConfig(options: BaseOptions): Promise<an
;

infuseAliases(config, alias);
await infuseWebpackModule(config, outDir, sourceMap);

return config;
}
16 changes: 14 additions & 2 deletions packages/@gluons/vue-pack/src/lib/createModuleConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { BaseOptions } from '@gluons/vue-pack-types';
import createBaseConfig from './createBaseConfig';
import infuseCJSOutput from './infuser/infuseCJSOutput';
import infuseESMOutput from './infuser/infuseESMOutput';
import infuseSSROutput from './infuser/infuseSSROutput';
import infuseWebpackModule from './infuser/infuseWebpackModule';
import infuseWebpackOptimization from './infuser/infuseWebpackOptimization';
import infuseWebpackPlugins from './infuser/infuseWebpackPlugins';

export type Options = BaseOptions & { moduleType: 'common' | 'es' };
export type Options = BaseOptions & { moduleType: 'common' | 'es' | 'ssr' };

/**
* Create module config via `webpack-chain`'s config instance.
Expand All @@ -18,6 +20,7 @@ export type Options = BaseOptions & { moduleType: 'common' | 'es' };
export default async function createModuleConfig(options: Options): Promise<any> {
const {
fileName,
outDir,
define,
sourceMap,
externals: { module: moduleExternals },
Expand All @@ -27,11 +30,20 @@ export default async function createModuleConfig(options: Options): Promise<any>

if (moduleType === 'common') {
infuseCJSOutput(config);
} else {
} else if (moduleType === 'es') {
infuseESMOutput(config);
} else {
infuseSSROutput(config);
config.target('node');
}

infuseWebpackOptimization(config, false);
await infuseWebpackModule({
config,
outDir,
sourceMap,
ssr: moduleType === 'ssr'
});
infuseWebpackPlugins({
config,
fileName,
Expand Down
Loading