From ce18fa6d82ae3ea357f8efbd0c625a2d3ffdec87 Mon Sep 17 00:00:00 2001 From: Matt Gadd Date: Fri, 1 Jun 2018 10:24:52 +0100 Subject: [PATCH 1/8] evergreen --- src/base.config.ts | 66 +++++++++++++++++++++++++++++++++++++--------- src/main.ts | 7 +++++ 2 files changed, 60 insertions(+), 13 deletions(-) diff --git a/src/base.config.ts b/src/base.config.ts index 6a054b70..a9dc2914 100644 --- a/src/base.config.ts +++ b/src/base.config.ts @@ -7,6 +7,7 @@ import I18nPlugin from '@dojo/webpack-contrib/i18n-plugin/I18nPlugin'; import * as ExtractTextPlugin from 'extract-text-webpack-plugin'; import { WebAppManifest, WebpackConfiguration } from './interfaces'; import * as loaderUtils from 'loader-utils'; +import * as ts from 'typescript'; const IgnorePlugin = require('webpack/lib/IgnorePlugin'); const AutoRequireWebpackPlugin = require('auto-require-webpack-plugin'); @@ -83,8 +84,31 @@ Copyright [JS Foundation](https://js.foundation/) & contributors All rights reserved `; +function importTransformer(basePath: string, lazyModules: string[]) { + return (context: any) => { + return (file: any) => ts.visitEachChild(file, visit, context); + function visit(node: any): any { + if (node.kind === ts.SyntaxKind.CallExpression) { + if (node.expression.kind === ts.SyntaxKind.ImportKeyword) { + node.arguments[0] = ts.addSyntheticLeadingComment( + node.arguments[0], + ts.SyntaxKind.MultiLineCommentTrivia, + ` webpackChunkName: "love-you" `, + false + ); + return node; + } + } + return ts.visitEachChild(node, visit, context); + } + }; +} + export default function webpackConfigFactory(args: any): WebpackConfiguration { const manifest: WebAppManifest = args.pwa && args.pwa.manifest; + const extensions = args.legacy ? ['.ts', '.tsx', '.js'] : ['.ts', '.tsx', '.mjs', '.js']; + const compilerOptions = args.legacy ? {} : { target: 'es6', module: 'esnext' }; + const features = args.legacy ? args.features : ['chrome']; const lazyModules = Object.keys(args.bundles || {}).reduce( (lazy, key) => { lazy.push(...args.bundles[key]); @@ -93,17 +117,24 @@ export default function webpackConfigFactory(args: any): WebpackConfiguration { [] as string[] ); - const tsLoaderOptions: any = { - onlyCompileBundledFiles: true, - instance: 'dojo' - }; + const customTransformers: any[] = []; if (lazyModules.length > 0) { - tsLoaderOptions.getCustomTransformers = () => ({ - before: [registryTransformer(basePath, lazyModules)] - }); + customTransformers.push(registryTransformer(basePath, lazyModules)); + if (!args.legacy) { + customTransformers.push(importTransformer(basePath, lazyModules)); + } } + const tsLoaderOptions: any = { + onlyCompileBundledFiles: true, + instance: 'dojo', + compilerOptions, + getCustomTransformers() { + return { before: customTransformers }; + } + }; + const postCssModuleLoader = ExtractTextPlugin.extract({ fallback: ['style-loader'], use: [ @@ -177,7 +208,7 @@ export default function webpackConfigFactory(args: any): WebpackConfiguration { }, resolve: { modules: [basePath, path.join(basePath, 'node_modules')], - extensions: ['.ts', '.tsx', '.js'] + extensions }, devtool: 'source-map', watchOptions: { ignored: /node_modules/ }, @@ -231,23 +262,32 @@ export default function webpackConfigFactory(args: any): WebpackConfiguration { include: allPaths, test: /\.ts(x)?$/, use: removeEmpty([ - args.features && { + features && { loader: '@dojo/webpack-contrib/static-build-loader', - options: { features: args.features } + options: { features } }, - getUMDCompatLoader({ bundles: args.bundles }), + args.legacy && getUMDCompatLoader({ bundles: args.bundles }), { loader: 'ts-loader', options: tsLoaderOptions } ]) }, + { + test: /\.mjs?$/, + use: removeEmpty([ + features && { + loader: '@dojo/webpack-contrib/static-build-loader', + options: { features } + } + ]) + }, { test: /\.js(x)?$/, use: removeEmpty([ - args.features && { + features && { loader: '@dojo/webpack-contrib/static-build-loader', - options: { features: args.features } + options: { features } }, 'umd-compat-loader' ]) diff --git a/src/main.ts b/src/main.ts index b3646f35..f0b862e6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -188,6 +188,13 @@ const command: Command = { default: 9999, type: 'number' }); + + options('legacy', { + describe: 'build app with legacy browser support', + alias: 'l', + default: true, + type: 'boolean' + }); }, run(helper: Helper, args: any) { console.log = () => {}; From 3e98dc59aa48d53789b42a12e13abc3ec399ebd3 Mon Sep 17 00:00:00 2001 From: Matt Gadd Date: Fri, 1 Jun 2018 10:58:24 +0100 Subject: [PATCH 2/8] fix arg passing and features --- src/base.config.ts | 3 ++- src/main.ts | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/base.config.ts b/src/base.config.ts index a9dc2914..d88d6287 100644 --- a/src/base.config.ts +++ b/src/base.config.ts @@ -8,6 +8,7 @@ import * as ExtractTextPlugin from 'extract-text-webpack-plugin'; import { WebAppManifest, WebpackConfiguration } from './interfaces'; import * as loaderUtils from 'loader-utils'; import * as ts from 'typescript'; +import getFeatures from '@dojo/webpack-contrib/static-build-loader/getFeatures'; const IgnorePlugin = require('webpack/lib/IgnorePlugin'); const AutoRequireWebpackPlugin = require('auto-require-webpack-plugin'); @@ -108,7 +109,7 @@ export default function webpackConfigFactory(args: any): WebpackConfiguration { const manifest: WebAppManifest = args.pwa && args.pwa.manifest; const extensions = args.legacy ? ['.ts', '.tsx', '.js'] : ['.ts', '.tsx', '.mjs', '.js']; const compilerOptions = args.legacy ? {} : { target: 'es6', module: 'esnext' }; - const features = args.legacy ? args.features : ['chrome']; + const features = args.legacy ? { ...(args.features || {}), ...getFeatures('chrome') } : args.features; const lazyModules = Object.keys(args.bundles || {}).reduce( (lazy, key) => { lazy.push(...args.bundles[key]); diff --git a/src/main.ts b/src/main.ts index f0b862e6..c0dd009c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -201,11 +201,11 @@ const command: Command = { const rc = helper.configuration.get() || {}; let config: webpack.Configuration; if (args.mode === 'dev') { - config = devConfigFactory(rc); + config = devConfigFactory({ ...rc, ...args }); } else if (args.mode === 'test') { - config = testConfigFactory(rc); + config = testConfigFactory({ ...rc, ...args }); } else { - config = distConfigFactory(rc); + config = distConfigFactory({ ...rc, ...args }); } if (args.serve) { From a6af121676b8be14a10e090b966cd37ebf91eba8 Mon Sep 17 00:00:00 2001 From: Matt Gadd Date: Fri, 1 Jun 2018 11:14:22 +0100 Subject: [PATCH 3/8] correct ternary --- src/base.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base.config.ts b/src/base.config.ts index d88d6287..67120a67 100644 --- a/src/base.config.ts +++ b/src/base.config.ts @@ -109,7 +109,7 @@ export default function webpackConfigFactory(args: any): WebpackConfiguration { const manifest: WebAppManifest = args.pwa && args.pwa.manifest; const extensions = args.legacy ? ['.ts', '.tsx', '.js'] : ['.ts', '.tsx', '.mjs', '.js']; const compilerOptions = args.legacy ? {} : { target: 'es6', module: 'esnext' }; - const features = args.legacy ? { ...(args.features || {}), ...getFeatures('chrome') } : args.features; + const features = args.legacy ? args.features : { ...(args.features || {}), ...getFeatures('chrome') }; const lazyModules = Object.keys(args.bundles || {}).reduce( (lazy, key) => { lazy.push(...args.bundles[key]); From fc4b64bd95382cee6a48cbcefd2813facf96d706 Mon Sep 17 00:00:00 2001 From: Matt Gadd Date: Fri, 1 Jun 2018 14:32:56 +0100 Subject: [PATCH 4/8] implement import transformer --- package.json | 2 +- src/base.config.ts | 45 +++++++++++++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 9f8f1d0e..8969ca3e 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "typescript": "2.6.1" }, "dependencies": { - "@dojo/webpack-contrib": "2.0.0", + "@dojo/webpack-contrib": "2.0.1", "@theintern/istanbul-loader": "1.0.0-beta.1", "auto-require-webpack-plugin": "1.0.1", "chalk": "2.3.0", diff --git a/src/base.config.ts b/src/base.config.ts index 67120a67..6304ec29 100644 --- a/src/base.config.ts +++ b/src/base.config.ts @@ -85,20 +85,37 @@ Copyright [JS Foundation](https://js.foundation/) & contributors All rights reserved `; -function importTransformer(basePath: string, lazyModules: string[]) { - return (context: any) => { - return (file: any) => ts.visitEachChild(file, visit, context); +function importTransformer(basePath: string, bundles: any = {}) { + return function(context: any) { + let resolvedModules: any; + return function(file: any) { + resolvedModules = file.resolvedModules; + return ts.visitEachChild(file, visit, context); + }; function visit(node: any): any { - if (node.kind === ts.SyntaxKind.CallExpression) { - if (node.expression.kind === ts.SyntaxKind.ImportKeyword) { - node.arguments[0] = ts.addSyntheticLeadingComment( - node.arguments[0], - ts.SyntaxKind.MultiLineCommentTrivia, - ` webpackChunkName: "love-you" `, - false - ); - return node; - } + if (node.kind === ts.SyntaxKind.CallExpression && node.expression.kind === ts.SyntaxKind.ImportKeyword) { + const moduleText = node.arguments[0].text; + const { resolvedFileName } = resolvedModules.get(moduleText); + let chunkName = slash( + resolvedFileName + .replace(basePath, '') + .replace('.ts', '') + .replace(/^\//, '') + ); + Object.keys(bundles).some(function(name) { + if (bundles[name].indexOf(slash(chunkName)) !== -1) { + chunkName = name; + return true; + } + return false; + }); + node.arguments[0] = ts.addSyntheticLeadingComment( + node.arguments[0], + ts.SyntaxKind.MultiLineCommentTrivia, + ` webpackChunkName: "${chunkName}" `, + false + ); + return node; } return ts.visitEachChild(node, visit, context); } @@ -123,7 +140,7 @@ export default function webpackConfigFactory(args: any): WebpackConfiguration { if (lazyModules.length > 0) { customTransformers.push(registryTransformer(basePath, lazyModules)); if (!args.legacy) { - customTransformers.push(importTransformer(basePath, lazyModules)); + customTransformers.push(importTransformer(basePath, args.bundles)); } } From 2e75c65c376c677aa7b998c5a77bbc1506974076 Mon Sep 17 00:00:00 2001 From: Matt Gadd Date: Fri, 1 Jun 2018 15:00:02 +0100 Subject: [PATCH 5/8] use transformer when not legacy --- src/base.config.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/base.config.ts b/src/base.config.ts index 6304ec29..a8ff6513 100644 --- a/src/base.config.ts +++ b/src/base.config.ts @@ -139,9 +139,10 @@ export default function webpackConfigFactory(args: any): WebpackConfiguration { if (lazyModules.length > 0) { customTransformers.push(registryTransformer(basePath, lazyModules)); - if (!args.legacy) { - customTransformers.push(importTransformer(basePath, args.bundles)); - } + } + + if (!args.legacy) { + customTransformers.push(importTransformer(basePath, args.bundles)); } const tsLoaderOptions: any = { From 53e26921491095a98a99d141a1f16670a8d94682 Mon Sep 17 00:00:00 2001 From: Matt Gadd Date: Fri, 1 Jun 2018 15:17:32 +0100 Subject: [PATCH 6/8] test evergreen --- package.json | 2 +- test-app/package.json | 2 ++ tests/integration/build.spec.ts | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 8969ca3e..b2419911 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "test:ci": "run-p --race serve test", "serve": "http-server -p 9999 -c-1 --silent", "test": "npm run artefact:package && npm run artefact:install && grunt dev && grunt intern:node --test-reporter --color && npm run artefact:build && cypress run", - "artefact:build": "cd test-app && npm run build:dist && npm run build:dev", + "artefact:build": "cd test-app && npm run build:dist:evergreen && shx mv output/dist output/dist-evergreen && npm run build:dev:evergreen && shx mv output/dev output/dev-evergreen && npm run build:dist && npm run build:dev && npm run build:dist:evergreen", "artefact:install": "cd test-app && shx rm -rf node_modules && npm i && npm run install-build-app", "artefact:package": "grunt dist && grunt release-publish-flat --dry-run && shx mv dist/dojo-cli-build-app-* dist/dojo-cli-build-app.tgz", "prettier": "prettier --write 'src/**/*.ts' 'tests/**/*.ts'", diff --git a/test-app/package.json b/test-app/package.json index 380673c6..06e45677 100644 --- a/test-app/package.json +++ b/test-app/package.json @@ -7,6 +7,8 @@ "install-build-app": "npm install --no-save ../dist/dojo-cli-build-app.tgz", "build:dist": "dojo build --mode dist", "build:dev": "dojo build --mode dev", + "build:dist:evergreen": "dojo build --mode dist --legacy false", + "build:dev:evergreen": "dojo build --mode dev --legacy false", "build:test": "dojo build --mode test" }, "author": "", diff --git a/tests/integration/build.spec.ts b/tests/integration/build.spec.ts index 9010fc61..bbe62417 100644 --- a/tests/integration/build.spec.ts +++ b/tests/integration/build.spec.ts @@ -4,6 +4,16 @@ describe('build', () => { cy.get('#div').should( 'contain', `Built with Build Time Render: true +Currently Rendered by BTR: false` + ); + cy.get('#app-root').should('contain', 'Lazy Widget using dojorc configuration'); + cy.get('script[src^="lazy"]').should('exist'); + cy.get('script[src^="src/Foo"]').should('exist'); + + cy.visit('/test-app/output/dist-evergreen'); + cy.get('#div').should( + 'contain', + `Built with Build Time Render: true Currently Rendered by BTR: false` ); cy.get('#app-root').should('contain', 'Lazy Widget using dojorc configuration'); @@ -16,6 +26,16 @@ Currently Rendered by BTR: false` cy.get('#div').should( 'contain', `Built with Build Time Render: true +Currently Rendered by BTR: false` + ); + cy.get('#app-root').should('contain', 'Lazy Widget using dojorc configuration'); + cy.get('script[src^="lazy"]').should('exist'); + cy.get('script[src^="src/Foo"]').should('exist'); + + cy.visit('/test-app/output/dev-evergreen'); + cy.get('#div').should( + 'contain', + `Built with Build Time Render: true Currently Rendered by BTR: false` ); cy.get('#app-root').should('contain', 'Lazy Widget using dojorc configuration'); From 36aee23c1821e0a1a4a9a9698537e03147f5e21e Mon Sep 17 00:00:00 2001 From: Matt Gadd Date: Fri, 1 Jun 2018 15:48:53 +0100 Subject: [PATCH 7/8] drop reporter --- cypress.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cypress.json b/cypress.json index 5ed541d5..a38153d7 100644 --- a/cypress.json +++ b/cypress.json @@ -6,9 +6,5 @@ "screenshotsFolder": "output/tests/screenshots", "videosFolder": "output/tests/videos", "supportFile": false, - "pluginsFile": false, - "reporter": "junit", - "reporterOptions": { - "mochaFile": "./output/report/junit.xml" - } + "pluginsFile": false } From 878a32557b4c4075a91c65ed602c484df694374e Mon Sep 17 00:00:00 2001 From: Matt Gadd Date: Fri, 1 Jun 2018 16:39:48 +0100 Subject: [PATCH 8/8] slashes --- src/base.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base.config.ts b/src/base.config.ts index a8ff6513..fc4203ec 100644 --- a/src/base.config.ts +++ b/src/base.config.ts @@ -100,7 +100,7 @@ function importTransformer(basePath: string, bundles: any = {}) { resolvedFileName .replace(basePath, '') .replace('.ts', '') - .replace(/^\//, '') + .replace(/^(\/|\\)/, '') ); Object.keys(bundles).some(function(name) { if (bundles[name].indexOf(slash(chunkName)) !== -1) {