diff --git a/packages/webpack5/__tests__/configuration/__snapshots__/angular.spec.ts.snap b/packages/webpack5/__tests__/configuration/__snapshots__/angular.spec.ts.snap new file mode 100644 index 000000000..321401b82 --- /dev/null +++ b/packages/webpack5/__tests__/configuration/__snapshots__/angular.spec.ts.snap @@ -0,0 +1,468 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`angular configuration for android 1`] = ` +"{ + mode: 'development', + externals: [ + 'package.json', + '~/package.json' + ], + devtool: 'inline-source-map', + target: 'node', + output: { + path: '__jest__/platforms/android/app/src/main/assets/app', + pathinfo: false, + publicPath: '', + libraryTarget: 'commonjs', + globalObject: 'global' + }, + resolve: { + symlinks: true, + alias: { + '~': 'appFullPath', + '@': 'appFullPath' + }, + extensions: [ + '.android.ts', + '.ts', + '.android.js', + '.js', + '.android.css', + '.css', + '.android.scss', + '.scss', + '.android.json', + '.json' + ] + }, + resolveLoader: { + modules: [ + 'node_modules/@nativescript/webpack/dist/loaders', + 'node_modules' + ] + }, + module: { + rules: [ + /* config.module.rule('js') */ + { + test: /\\\\.js$/, + exclude: [ + /node_modules/ + ], + use: [ + /* config.module.rule('js').use('babel-loader') */ + { + loader: 'babel-loader', + options: { + generatorOpts: { + compact: false + } + } + } + ] + }, + /* config.module.rule('css') */ + { + test: /\\\\.css$/, + use: [ + /* config.module.rule('css').use('apply-css-loader') */ + { + loader: 'apply-css-loader' + }, + /* config.module.rule('css').use('css2json-loader') */ + { + loader: 'css2json-loader' + } + ] + }, + /* config.module.rule('scss') */ + { + test: /\\\\.scss$/, + use: [ + /* config.module.rule('scss').use('apply-css-loader') */ + { + loader: 'apply-css-loader' + }, + /* config.module.rule('scss').use('css2json-loader') */ + { + loader: 'css2json-loader' + }, + /* config.module.rule('scss').use('sass-loader') */ + { + loader: 'sass-loader' + } + ] + }, + /* config.module.rule('angular') */ + { + test: /(?:\\\\.ngfactory.js|\\\\.ngstyle\\\\.js|\\\\.ts)$/, + use: [ + /* config.module.rule('angular').use('@ngtools/webpack') */ + { + loader: '@ngtools/webpack' + } + ] + }, + /* config.module.rule('@angular/core') */ + { + test: /[\\\\/\\\\\\\\]@angular[\\\\/\\\\\\\\]core[\\\\/\\\\\\\\].+\\\\.js$/, + parser: { + system: true + } + }, + /* config.module.rule('html') */ + { + test: /\\\\.html$/, + use: [ + /* config.module.rule('html').use('raw-loader') */ + { + loader: 'raw-loader' + } + ] + } + ] + }, + optimization: { + splitChunks: { + cacheGroups: { + defaultVendor: { + test: /[\\\\\\\\/]node_modules[\\\\\\\\/]/, + priority: -10, + name: 'vendor', + chunks: 'all' + } + } + }, + minimizer: [ + /* config.optimization.minimizer('TerserPlugin') */ + new TerserPlugin( + { + terserOptions: { + compress: { + collapse_vars: false, + sequences: false + }, + keep_fnames: true + } + } + ) + ] + }, + plugins: [ + /* config.plugin('ForkTsCheckerWebpackPlugin') */ + new ForkTsCheckerWebpackPlugin( + { + typescript: { + memoryLimit: 4096 + } + } + ), + /* config.plugin('CleanWebpackPlugin') */ + new CleanWebpackPlugin( + { + cleanOnceBeforeBuildPatterns: [ + '__jest__/platforms/android/app/src/main/assets/app/**/*' + ], + verbose: false + } + ), + /* config.plugin('DefinePlugin') */ + new DefinePlugin( + { + __DEV__: true, + __NS_WEBPACK__: true, + __CSS_PARSER__: '\\"css-tree\\"', + __ANDROID__: true, + __IOS__: false, + 'global.isAndroid': true, + 'global.isIOS': false, + process: 'global.process' + } + ), + /* config.plugin('CopyWebpackPlugin') */ + new CopyPlugin( + { + patterns: [ + { + from: 'assets/**', + context: '__jest__/src', + noErrorOnMissing: true, + globOptions: { + dot: false + } + }, + { + from: 'fonts/**', + context: '__jest__/src', + noErrorOnMissing: true, + globOptions: { + dot: false + } + }, + { + from: '**/*.+(jpg|png)', + context: '__jest__/src', + noErrorOnMissing: true, + globOptions: { + dot: false + } + } + ] + } + ), + /* config.plugin('WatchStatePlugin') */ + new WatchStatePlugin(), + /* config.plugin('AngularCompilerPlugin') */ + new AngularCompilerPlugin( + { + tsConfigPath: '__jest__/tsconfig.json', + mainPath: '__jest__/src/app.js', + platformTransformers: [ + function () { /* omitted long function */ } + ] + } + ) + ], + entry: { + bundle: [ + '@nativescript/core/globals/index.js', + '__jest__/src/app.js' + ] + } +}" +`; + +exports[`angular configuration for ios 1`] = ` +"{ + mode: 'development', + externals: [ + 'package.json', + '~/package.json' + ], + devtool: 'inline-source-map', + target: 'node', + output: { + path: '__jest__/platforms/ios/__jest__/app', + pathinfo: false, + publicPath: '', + libraryTarget: 'commonjs', + globalObject: 'global' + }, + resolve: { + symlinks: true, + alias: { + '~': 'appFullPath', + '@': 'appFullPath' + }, + extensions: [ + '.ios.ts', + '.ts', + '.ios.js', + '.js', + '.ios.css', + '.css', + '.ios.scss', + '.scss', + '.ios.json', + '.json' + ] + }, + resolveLoader: { + modules: [ + 'node_modules/@nativescript/webpack/dist/loaders', + 'node_modules' + ] + }, + module: { + rules: [ + /* config.module.rule('js') */ + { + test: /\\\\.js$/, + exclude: [ + /node_modules/ + ], + use: [ + /* config.module.rule('js').use('babel-loader') */ + { + loader: 'babel-loader', + options: { + generatorOpts: { + compact: false + } + } + } + ] + }, + /* config.module.rule('css') */ + { + test: /\\\\.css$/, + use: [ + /* config.module.rule('css').use('apply-css-loader') */ + { + loader: 'apply-css-loader' + }, + /* config.module.rule('css').use('css2json-loader') */ + { + loader: 'css2json-loader' + } + ] + }, + /* config.module.rule('scss') */ + { + test: /\\\\.scss$/, + use: [ + /* config.module.rule('scss').use('apply-css-loader') */ + { + loader: 'apply-css-loader' + }, + /* config.module.rule('scss').use('css2json-loader') */ + { + loader: 'css2json-loader' + }, + /* config.module.rule('scss').use('sass-loader') */ + { + loader: 'sass-loader' + } + ] + }, + /* config.module.rule('angular') */ + { + test: /(?:\\\\.ngfactory.js|\\\\.ngstyle\\\\.js|\\\\.ts)$/, + use: [ + /* config.module.rule('angular').use('@ngtools/webpack') */ + { + loader: '@ngtools/webpack' + } + ] + }, + /* config.module.rule('@angular/core') */ + { + test: /[\\\\/\\\\\\\\]@angular[\\\\/\\\\\\\\]core[\\\\/\\\\\\\\].+\\\\.js$/, + parser: { + system: true + } + }, + /* config.module.rule('html') */ + { + test: /\\\\.html$/, + use: [ + /* config.module.rule('html').use('raw-loader') */ + { + loader: 'raw-loader' + } + ] + } + ] + }, + optimization: { + splitChunks: { + cacheGroups: { + defaultVendor: { + test: /[\\\\\\\\/]node_modules[\\\\\\\\/]/, + priority: -10, + name: 'vendor', + chunks: 'all' + } + } + }, + minimizer: [ + /* config.optimization.minimizer('TerserPlugin') */ + new TerserPlugin( + { + terserOptions: { + compress: { + collapse_vars: true, + sequences: true + }, + keep_fnames: true + } + } + ) + ] + }, + plugins: [ + /* config.plugin('ForkTsCheckerWebpackPlugin') */ + new ForkTsCheckerWebpackPlugin( + { + typescript: { + memoryLimit: 4096 + } + } + ), + /* config.plugin('CleanWebpackPlugin') */ + new CleanWebpackPlugin( + { + cleanOnceBeforeBuildPatterns: [ + '__jest__/platforms/ios/__jest__/app/**/*' + ], + verbose: false + } + ), + /* config.plugin('DefinePlugin') */ + new DefinePlugin( + { + __DEV__: true, + __NS_WEBPACK__: true, + __CSS_PARSER__: '\\"css-tree\\"', + __ANDROID__: false, + __IOS__: true, + 'global.isAndroid': false, + 'global.isIOS': true, + process: 'global.process' + } + ), + /* config.plugin('CopyWebpackPlugin') */ + new CopyPlugin( + { + patterns: [ + { + from: 'assets/**', + context: '__jest__/src', + noErrorOnMissing: true, + globOptions: { + dot: false + } + }, + { + from: 'fonts/**', + context: '__jest__/src', + noErrorOnMissing: true, + globOptions: { + dot: false + } + }, + { + from: '**/*.+(jpg|png)', + context: '__jest__/src', + noErrorOnMissing: true, + globOptions: { + dot: false + } + } + ] + } + ), + /* config.plugin('WatchStatePlugin') */ + new WatchStatePlugin(), + /* config.plugin('AngularCompilerPlugin') */ + new AngularCompilerPlugin( + { + tsConfigPath: '__jest__/tsconfig.json', + mainPath: '__jest__/src/app.js', + platformTransformers: [ + function () { /* omitted long function */ } + ] + } + ) + ], + entry: { + bundle: [ + '@nativescript/core/globals/index.js', + '__jest__/src/app.js' + ], + 'tns_modules/@nativescript/core/inspector_modules': [ + '@nativescript/core/inspector_modules' + ] + } +}" +`; diff --git a/packages/webpack5/__tests__/configuration/__snapshots__/react.spec.ts.snap b/packages/webpack5/__tests__/configuration/__snapshots__/react.spec.ts.snap index 38dbadddc..6b2b24480 100644 --- a/packages/webpack5/__tests__/configuration/__snapshots__/react.spec.ts.snap +++ b/packages/webpack5/__tests__/configuration/__snapshots__/react.spec.ts.snap @@ -196,7 +196,7 @@ exports[`react configuration > android > adds ReactRefreshWebpackPlugin when HMR patterns: [ { from: 'assets/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -204,7 +204,7 @@ exports[`react configuration > android > adds ReactRefreshWebpackPlugin when HMR }, { from: 'fonts/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -212,7 +212,7 @@ exports[`react configuration > android > adds ReactRefreshWebpackPlugin when HMR }, { from: '**/*.+(jpg|png)', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -238,7 +238,7 @@ exports[`react configuration > android > adds ReactRefreshWebpackPlugin when HMR entry: { bundle: [ '@nativescript/core/globals/index.js', - 'src/app.js' + '__jest__/src/app.js' ] } }" @@ -429,7 +429,7 @@ exports[`react configuration > android > base config 1`] = ` patterns: [ { from: 'assets/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -437,7 +437,7 @@ exports[`react configuration > android > base config 1`] = ` }, { from: 'fonts/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -445,7 +445,7 @@ exports[`react configuration > android > base config 1`] = ` }, { from: '**/*.+(jpg|png)', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -460,7 +460,7 @@ exports[`react configuration > android > base config 1`] = ` entry: { bundle: [ '@nativescript/core/globals/index.js', - 'src/app.js' + '__jest__/src/app.js' ] } }" @@ -662,7 +662,7 @@ exports[`react configuration > ios > adds ReactRefreshWebpackPlugin when HMR ena patterns: [ { from: 'assets/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -670,7 +670,7 @@ exports[`react configuration > ios > adds ReactRefreshWebpackPlugin when HMR ena }, { from: 'fonts/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -678,7 +678,7 @@ exports[`react configuration > ios > adds ReactRefreshWebpackPlugin when HMR ena }, { from: '**/*.+(jpg|png)', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -704,7 +704,7 @@ exports[`react configuration > ios > adds ReactRefreshWebpackPlugin when HMR ena entry: { bundle: [ '@nativescript/core/globals/index.js', - 'src/app.js' + '__jest__/src/app.js' ], 'tns_modules/@nativescript/core/inspector_modules': [ '@nativescript/core/inspector_modules' @@ -898,7 +898,7 @@ exports[`react configuration > ios > base config 1`] = ` patterns: [ { from: 'assets/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -906,7 +906,7 @@ exports[`react configuration > ios > base config 1`] = ` }, { from: 'fonts/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -914,7 +914,7 @@ exports[`react configuration > ios > base config 1`] = ` }, { from: '**/*.+(jpg|png)', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -929,7 +929,7 @@ exports[`react configuration > ios > base config 1`] = ` entry: { bundle: [ '@nativescript/core/globals/index.js', - 'src/app.js' + '__jest__/src/app.js' ], 'tns_modules/@nativescript/core/inspector_modules': [ '@nativescript/core/inspector_modules' diff --git a/packages/webpack5/__tests__/configuration/__snapshots__/svelte.spec.ts.snap b/packages/webpack5/__tests__/configuration/__snapshots__/svelte.spec.ts.snap index d7abbb0d3..9ada8af46 100644 --- a/packages/webpack5/__tests__/configuration/__snapshots__/svelte.spec.ts.snap +++ b/packages/webpack5/__tests__/configuration/__snapshots__/svelte.spec.ts.snap @@ -209,7 +209,7 @@ exports[`svelte configuration for android 1`] = ` patterns: [ { from: 'assets/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -217,7 +217,7 @@ exports[`svelte configuration for android 1`] = ` }, { from: 'fonts/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -225,7 +225,7 @@ exports[`svelte configuration for android 1`] = ` }, { from: '**/*.+(jpg|png)', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -240,7 +240,7 @@ exports[`svelte configuration for android 1`] = ` entry: { bundle: [ '@nativescript/core/globals/index.js', - 'src/app.js' + '__jest__/src/app.js' ] } }" @@ -455,7 +455,7 @@ exports[`svelte configuration for ios 1`] = ` patterns: [ { from: 'assets/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -463,7 +463,7 @@ exports[`svelte configuration for ios 1`] = ` }, { from: 'fonts/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -471,7 +471,7 @@ exports[`svelte configuration for ios 1`] = ` }, { from: '**/*.+(jpg|png)', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -486,7 +486,7 @@ exports[`svelte configuration for ios 1`] = ` entry: { bundle: [ '@nativescript/core/globals/index.js', - 'src/app.js' + '__jest__/src/app.js' ], 'tns_modules/@nativescript/core/inspector_modules': [ '@nativescript/core/inspector_modules' diff --git a/packages/webpack5/__tests__/configuration/__snapshots__/vue.spec.ts.snap b/packages/webpack5/__tests__/configuration/__snapshots__/vue.spec.ts.snap index bb499c011..dfe35ed2d 100644 --- a/packages/webpack5/__tests__/configuration/__snapshots__/vue.spec.ts.snap +++ b/packages/webpack5/__tests__/configuration/__snapshots__/vue.spec.ts.snap @@ -211,7 +211,7 @@ exports[`vue configuration for android 1`] = ` patterns: [ { from: 'assets/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -219,7 +219,7 @@ exports[`vue configuration for android 1`] = ` }, { from: 'fonts/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -227,7 +227,7 @@ exports[`vue configuration for android 1`] = ` }, { from: '**/*.+(jpg|png)', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -242,7 +242,7 @@ exports[`vue configuration for android 1`] = ` entry: { bundle: [ '@nativescript/core/globals/index.js', - 'src/app.js' + '__jest__/src/app.js' ] } }" @@ -459,7 +459,7 @@ exports[`vue configuration for ios 1`] = ` patterns: [ { from: 'assets/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -467,7 +467,7 @@ exports[`vue configuration for ios 1`] = ` }, { from: 'fonts/**', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -475,7 +475,7 @@ exports[`vue configuration for ios 1`] = ` }, { from: '**/*.+(jpg|png)', - context: 'src', + context: '__jest__/src', noErrorOnMissing: true, globOptions: { dot: false @@ -490,7 +490,7 @@ exports[`vue configuration for ios 1`] = ` entry: { bundle: [ '@nativescript/core/globals/index.js', - 'src/app.js' + '__jest__/src/app.js' ], 'tns_modules/@nativescript/core/inspector_modules': [ '@nativescript/core/inspector_modules' diff --git a/packages/webpack5/__tests__/configuration/angular.spec.ts b/packages/webpack5/__tests__/configuration/angular.spec.ts new file mode 100644 index 000000000..c8f16372a --- /dev/null +++ b/packages/webpack5/__tests__/configuration/angular.spec.ts @@ -0,0 +1,28 @@ +import Config from 'webpack-chain'; +import angular from '../../src/configuration/angular'; +import { init } from '../../src'; + +jest.mock( + '@ngtools/webpack', + () => { + class AngularCompilerPlugin {} + + return { + AngularCompilerPlugin, + }; + }, + { virtual: true } +); + +describe.only('angular configuration', () => { + const platforms = ['ios', 'android']; + + for (let platform of platforms) { + it(`for ${platform}`, () => { + init({ + [platform]: true, + }); + expect(angular(new Config()).toString()).toMatchSnapshot(); + }); + } +}); diff --git a/packages/webpack5/__tests__/configuration/react.spec.ts b/packages/webpack5/__tests__/configuration/react.spec.ts index ca3e413fe..9283d58f5 100644 --- a/packages/webpack5/__tests__/configuration/react.spec.ts +++ b/packages/webpack5/__tests__/configuration/react.spec.ts @@ -1,4 +1,3 @@ -// @ts-ignore import Config from 'webpack-chain'; import react from '../../src/configuration/react'; import { init } from '../../src'; diff --git a/packages/webpack5/__tests__/configuration/svelte.spec.ts b/packages/webpack5/__tests__/configuration/svelte.spec.ts index c89102aa3..24eaf15e3 100644 --- a/packages/webpack5/__tests__/configuration/svelte.spec.ts +++ b/packages/webpack5/__tests__/configuration/svelte.spec.ts @@ -1,8 +1,11 @@ -// @ts-ignore import Config from 'webpack-chain'; import svelte from '../../src/configuration/svelte'; import { init } from '../../src'; +mockFile('./svelte.config.js', ''); +// jest.mock('__jest__/svelte.config.js', () => { +// }, { virtual: true }) + describe.only('svelte configuration', () => { const platforms = ['ios', 'android']; diff --git a/packages/webpack5/__tests__/configuration/vue.spec.ts b/packages/webpack5/__tests__/configuration/vue.spec.ts index f43ef9964..ec6a626f5 100644 --- a/packages/webpack5/__tests__/configuration/vue.spec.ts +++ b/packages/webpack5/__tests__/configuration/vue.spec.ts @@ -1,4 +1,3 @@ -// @ts-ignore import Config from 'webpack-chain'; import vue from '../../src/configuration/vue'; import { init } from '../../src'; diff --git a/packages/webpack5/jest.config.js b/packages/webpack5/jest.config.js index 0febf167d..d0d1e8abd 100644 --- a/packages/webpack5/jest.config.js +++ b/packages/webpack5/jest.config.js @@ -6,5 +6,10 @@ module.exports = { }, setupFiles: [ '/jest.setup.ts' - ] + ], + globals: { + 'ts-jest': { + tsconfig: 'tsconfig.jest.json' + } + } }; diff --git a/packages/webpack5/jest.setup.ts b/packages/webpack5/jest.setup.ts index 82b311c92..3221dede3 100644 --- a/packages/webpack5/jest.setup.ts +++ b/packages/webpack5/jest.setup.ts @@ -1,5 +1,15 @@ +// define our global helpers +declare global { + function mockFile(path: string, content: string); +} + +// enable TEST mode +global.__TEST__ = true; + // we are mocking the cwd for the tests, since webpack needs absolute paths // and we don't want them in tests +import dedent from 'ts-dedent'; + process.cwd = () => '__jest__'; // a virtual mock for package.json @@ -22,10 +32,51 @@ jest.mock('cosmiconfig', () => ({ }, })); -jest.mock('path', () => ({ - ...jest.requireActual('path'), - // we are mocking resolve to just simply join the paths for tests - resolve(...args) { - return args.join('/'); - }, -})); +jest.mock('path', () => { + const path = jest.requireActual('path'); + return { + ...path, + resolve(...args) { + if (args[0] === '__jest__') { + return path.join(...args); + } + + const resolved = path.resolve(...args); + if (resolved.includes('__jest__')) { + const li = resolved.lastIndexOf('__jest__'); + return resolved.substr(li); + } + + return resolved; + }, + }; +}); + +const mockedFiles: { [path: string]: string } = {}; + +global.mockFile = function mockFile(path, content) { + const unionFS = require('unionfs').default; + const Volume = require('memfs').Volume; + + // reset to fs + unionFS.reset(); + + // add mocked file + mockedFiles[path] = dedent(content); + + // create new volume + const vol = Volume.fromJSON(mockedFiles, '__jest__'); + + // use the new volume + unionFS.use(vol as any); +}; + +jest.mock('fs', () => { + const fs = jest.requireActual('fs'); + const unionFS = require('unionfs').default; + unionFS.reset = () => { + unionFS.fss = [fs]; + }; + + return unionFS.use(fs); +}); diff --git a/packages/webpack5/package.json b/packages/webpack5/package.json index 9dd4ad202..366cc7c2f 100644 --- a/packages/webpack5/package.json +++ b/packages/webpack5/package.json @@ -28,6 +28,7 @@ "css-loader": "^5.0.1", "fork-ts-checker-webpack-plugin": "^6.0.3", "loader-utils": "^2.0.0", + "raw-loader": "^4.0.2", "react-refresh": "^0.9.0", "sass": "^1.29.0", "sass-loader": "^10.1.0", @@ -50,9 +51,11 @@ "@types/loader-utils": "^2.0.1", "@types/terser-webpack-plugin": "^5.0.2", "jest": "^26.6.3", + "memfs": "^3.2.0", "nativescript-vue-template-compiler": "^2.8.2", "ts-jest": "^26.4.4", - "typescript": "^4.1.2" + "typescript": "^4.1.2", + "unionfs": "^4.4.0" }, "peerDependencies": { "nativescript-vue-template-compiler": "^2.8.1" diff --git a/packages/webpack5/src/configuration/angular.ts b/packages/webpack5/src/configuration/angular.ts index 6499805cd..85c29dd17 100644 --- a/packages/webpack5/src/configuration/angular.ts +++ b/packages/webpack5/src/configuration/angular.ts @@ -1,10 +1,48 @@ import Config from 'webpack-chain'; +import path from 'path'; -import { IWebpackEnv } from '../index'; +import { getEntryPath, getProjectRootPath } from '../helpers/project'; +import { env as _env, IWebpackEnv } from '../index'; import base from './base'; -export default function (config: Config, env: IWebpackEnv): Config { +export default function (config: Config, env: IWebpackEnv = _env): Config { base(config, env); + const tsConfigPath = path.join(getProjectRootPath(), 'tsconfig.json'); + + // remove default ts rule + config.module.rules.delete('ts'); + + config.module + .rule('angular') + .test(/(?:\.ngfactory.js|\.ngstyle\.js|\.ts)$/) + .use('@ngtools/webpack') + .loader('@ngtools/webpack'); + + config.module + .rule('@angular/core') + .test(/[\/\\]@angular[\/\\]core[\/\\].+\.js$/) + .parser({ system: true }); + + // set up html + config.module + .rule('html') + .test(/\.html$/) + .use('raw-loader') + .loader('raw-loader'); + + config.plugin('AngularCompilerPlugin').use(getAngularCompilerPlugin(), [ + { + tsConfigPath, + mainPath: getEntryPath(), + platformTransformers: [require('../transformers/NativeClass').default], + }, + ]); + return config; } + +function getAngularCompilerPlugin() { + const { AngularCompilerPlugin } = require('@ngtools/webpack'); + return AngularCompilerPlugin; +} diff --git a/packages/webpack5/src/configuration/svelte.ts b/packages/webpack5/src/configuration/svelte.ts index 6a791da70..99e5246e9 100644 --- a/packages/webpack5/src/configuration/svelte.ts +++ b/packages/webpack5/src/configuration/svelte.ts @@ -60,6 +60,8 @@ function getSvelteConfig(): { preprocess: any } | undefined { }); return require(resolvedPath); } catch (err) { + // todo: remove when jest supports mocking require.resolve + if (__TEST__) return; error('Could not find svelte.config.js.', err); } } diff --git a/packages/webpack5/src/globals.d.ts b/packages/webpack5/src/globals.d.ts new file mode 100644 index 000000000..b861b6498 --- /dev/null +++ b/packages/webpack5/src/globals.d.ts @@ -0,0 +1 @@ +declare var __TEST__: boolean; diff --git a/packages/webpack5/src/helpers/project.ts b/packages/webpack5/src/helpers/project.ts index dd4f40bd0..a0404b19c 100644 --- a/packages/webpack5/src/helpers/project.ts +++ b/packages/webpack5/src/helpers/project.ts @@ -16,7 +16,7 @@ export function getAbsoluteDistPath() { export function getEntryPath() { const packageJson = getPackageJson(); - return resolve(packageJson.main); + return resolve(getProjectRootPath(), packageJson.main); } export function getDistPath() { diff --git a/packages/webpack5/src/index.ts b/packages/webpack5/src/index.ts index c50b54d61..73aa37bff 100644 --- a/packages/webpack5/src/index.ts +++ b/packages/webpack5/src/index.ts @@ -59,8 +59,10 @@ export function useConfig(config: keyof typeof defaultConfigs | false) { } export function chainWebpack( - chainFn: (config: Config, env: IWebpackEnv) => any + chainFn: (config: Config, env: IWebpackEnv) => any, + options?: { last?: boolean } ) { + // todo: handle options.last by storing them in a separate array? webpackChains.push(chainFn); } diff --git a/packages/webpack5/tsconfig.jest.json b/packages/webpack5/tsconfig.jest.json new file mode 100644 index 000000000..e3a2a33ad --- /dev/null +++ b/packages/webpack5/tsconfig.jest.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "include": ["src", "__tests__", "jest.setup.ts"] +}