mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-19 14:20:22 +08:00
Merge branch 'feat/webpack5' of https://github.com/NativeScript/NativeScript
This commit is contained in:
8
.gitignore
vendored
8
.gitignore
vendored
@ -6,10 +6,10 @@
|
||||
/out-tsc
|
||||
|
||||
# dependencies
|
||||
node_modules
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
pnpm-lock.yaml
|
||||
**/node_modules
|
||||
**/package-lock.json
|
||||
**/yarn.lock
|
||||
**/pnpm-lock.yaml
|
||||
|
||||
# IDEs and editors
|
||||
.idea
|
||||
|
3
packages/webpack5/.gitignore
vendored
Normal file
3
packages/webpack5/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
#
|
||||
dist
|
||||
coverage
|
6
packages/webpack5/.prettierrc.json
Normal file
6
packages/webpack5/.prettierrc.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"useTabs": true,
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true
|
||||
}
|
30
packages/webpack5/README.md
Normal file
30
packages/webpack5/README.md
Normal file
@ -0,0 +1,30 @@
|
||||
@nativescript/webpack rewrite
|
||||
|
||||
The rewrite allows us to simplify things, and introduce some breaking changes.
|
||||
Listing them here, so we can keep track of them - will be in the merge commit, and the release notes once we are ready.
|
||||
|
||||
BREAKING CHANGES:
|
||||
- `package.json` main should now use a relative path to the package.json instead of the app directory
|
||||
|
||||
For example (given we have a `src` directory where our app is):
|
||||
|
||||
`"main": "app.js"` becomes `"main": "src/app.js"` **OR** `"main": "src/app.ts"` (whether using JS or TS)
|
||||
|
||||
This simplifies things, and will allow ctrl/cmd + clicking on the filename in some editors.
|
||||
|
||||
- `postinstall` scripts have been removed.
|
||||
|
||||
The configuration will not need to change in the user projects between updates.
|
||||
|
||||
For existing projects we will provide an easy upgrade path, through `ns migrate` and a binary in the package.
|
||||
|
||||
For new projects `ns create` should create the config file by invoking a binary in the package.
|
||||
|
||||
- removed resolutions for short imports - use full imports instead.
|
||||
|
||||
For example:
|
||||
```
|
||||
import http from 'http'
|
||||
// becomes
|
||||
import { http } from '@nativescript/core'
|
||||
```
|
47
packages/webpack5/__tests__/cli/parseEnvFlags.spec.ts
Normal file
47
packages/webpack5/__tests__/cli/parseEnvFlags.spec.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { parseEnvFlags } from '../../src/cli/parseEnvFlags';
|
||||
|
||||
describe.only('parseEnvFlags', () => {
|
||||
it('parses all possible flags', () => {
|
||||
const res = parseEnvFlags([
|
||||
'--env', // invalid
|
||||
'--env.foo',
|
||||
'--env.externals=ext1',
|
||||
'--env.externals=ext2',
|
||||
'--env.externals=ext3',
|
||||
'--env.externals=ext4',
|
||||
'--env.externals=ext4',
|
||||
'--env.externals=/path/to/a/very/long/path with spaces/foo.js',
|
||||
'--env.externals=~/package.json',
|
||||
'--env.externals=package.json',
|
||||
'--env.ios=false',
|
||||
'--env.android',
|
||||
'--env.verbose',
|
||||
'--env.sourceMap',
|
||||
'--env.appPath=app',
|
||||
'--env.appResourcesPath=App_Resources',
|
||||
'--env.num=5',
|
||||
'--env.float=5.4',
|
||||
'--env.numArray=3',
|
||||
'--env.numArray=4',
|
||||
'--env.numArray=5',
|
||||
'--no-hmr',
|
||||
'--not-env-flag',
|
||||
]);
|
||||
|
||||
expect(res).toBeDefined();
|
||||
expect(res.foo).toBe(true);
|
||||
expect(res.externals).toBeInstanceOf(Array);
|
||||
expect(res.externals.length).toBe(8);
|
||||
expect(res.ios).toBe(false);
|
||||
expect(res.android).toBe(true);
|
||||
expect(res.verbose).toBe(true);
|
||||
expect(res.sourceMap).toBe(true);
|
||||
expect(res.sourceMap).toBe(true);
|
||||
expect(res.appPath).toBe('app');
|
||||
expect(res.appResourcesPath).toBe('App_Resources');
|
||||
expect(res.num).toBe(5);
|
||||
expect(res.float).toBe(5.4);
|
||||
expect(res.numArray).toStrictEqual([3, 4, 5]);
|
||||
expect(Object.keys(res).length).toBe(11);
|
||||
});
|
||||
});
|
@ -0,0 +1,714 @@
|
||||
// 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',
|
||||
watchOptions: {
|
||||
ignored: [
|
||||
'__jest__/platforms/**',
|
||||
'__jest__/App_Resources/**'
|
||||
]
|
||||
},
|
||||
ignoreWarnings: [
|
||||
/System.import\\\\(\\\\) is deprecated/,
|
||||
/Zone\\\\.js does not support native async\\\\/await/,
|
||||
/environment.(\\\\w+).ts is part of the TypeScript compilation but it's unused/
|
||||
],
|
||||
output: {
|
||||
path: '__jest__/platforms/android/app/src/main/assets/app',
|
||||
pathinfo: false,
|
||||
publicPath: '',
|
||||
libraryTarget: 'commonjs',
|
||||
globalObject: 'global',
|
||||
clean: true
|
||||
},
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
alias: {
|
||||
'~': '__jest__/src',
|
||||
'@': '__jest__/src'
|
||||
},
|
||||
extensions: [
|
||||
'.android.ts',
|
||||
'.ts',
|
||||
'.android.js',
|
||||
'.js',
|
||||
'.android.css',
|
||||
'.css',
|
||||
'.android.scss',
|
||||
'.scss',
|
||||
'.android.json',
|
||||
'.json'
|
||||
],
|
||||
mainFields: [
|
||||
'module',
|
||||
'main'
|
||||
],
|
||||
modules: [
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
resolveLoader: {
|
||||
modules: [
|
||||
'__jest__/node_modules/@nativescript/webpack/dist/loaders',
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
/* config.module.rule('bundle') */
|
||||
{
|
||||
enforce: 'post',
|
||||
test: '__jest__/src/app.js',
|
||||
use: [
|
||||
/* config.module.rule('bundle').use('app-css-loader') */
|
||||
{
|
||||
loader: 'app-css-loader',
|
||||
options: {
|
||||
platform: 'android'
|
||||
}
|
||||
},
|
||||
/* config.module.rule('bundle').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
injectHMRRuntime: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('workers') */
|
||||
{
|
||||
test: /\\\\.(js|ts)$/,
|
||||
exclude: [
|
||||
/node_modules/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('workers').use('nativescript-worker-loader') */
|
||||
{
|
||||
loader: 'nativescript-worker-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('css') */
|
||||
{
|
||||
test: /\\\\.css$/,
|
||||
exclude: [
|
||||
/\\\\.component\\\\.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('css').use('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('scss') */
|
||||
{
|
||||
test: /\\\\.scss$/,
|
||||
exclude: [
|
||||
/\\\\.component\\\\.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('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
/* 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'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('css|component') */
|
||||
{
|
||||
test: /\\\\.component\\\\.css$/,
|
||||
use: [
|
||||
/* config.module.rule('css|component').use('raw-loader') */
|
||||
{
|
||||
loader: 'raw-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('scss|component') */
|
||||
{
|
||||
test: /\\\\.component\\\\.scss$/,
|
||||
use: [
|
||||
/* config.module.rule('scss|component').use('raw-loader') */
|
||||
{
|
||||
loader: 'raw-loader'
|
||||
},
|
||||
/* config.module.rule('scss|component').use('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
/* config.module.rule('scss|component').use('sass-loader') */
|
||||
{
|
||||
loader: 'sass-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_infinity: true,
|
||||
drop_console: false,
|
||||
global_defs: {
|
||||
__UGLIFIED__: true
|
||||
}
|
||||
},
|
||||
keep_fnames: true,
|
||||
keep_classnames: true
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
/* config.plugin('PlatformSuffixPlugin') */
|
||||
new PlatformSuffixPlugin(
|
||||
{
|
||||
platform: 'android'
|
||||
}
|
||||
),
|
||||
/* config.plugin('ContextExclusionPlugin|App_Resources') */
|
||||
new ContextExclusionPlugin(
|
||||
/(.*)App_Resources(.*)/
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__NS_ENV_VERBOSE__: false,
|
||||
__NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]',
|
||||
__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,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: 'fonts/**',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: '**/*.+(jpg|png)',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
),
|
||||
/* 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',
|
||||
'@nativescript/core/ui/frame',
|
||||
'@nativescript/core/ui/frame/activity'
|
||||
]
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`angular configuration for ios 1`] = `
|
||||
"{
|
||||
mode: 'development',
|
||||
externals: [
|
||||
'package.json',
|
||||
'~/package.json'
|
||||
],
|
||||
devtool: 'inline-source-map',
|
||||
target: 'node',
|
||||
watchOptions: {
|
||||
ignored: [
|
||||
'__jest__/platforms/**',
|
||||
'__jest__/App_Resources/**'
|
||||
]
|
||||
},
|
||||
ignoreWarnings: [
|
||||
/System.import\\\\(\\\\) is deprecated/,
|
||||
/Zone\\\\.js does not support native async\\\\/await/,
|
||||
/environment.(\\\\w+).ts is part of the TypeScript compilation but it's unused/
|
||||
],
|
||||
output: {
|
||||
path: '__jest__/platforms/ios/jest/app',
|
||||
pathinfo: false,
|
||||
publicPath: '',
|
||||
libraryTarget: 'commonjs',
|
||||
globalObject: 'global',
|
||||
clean: true
|
||||
},
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
alias: {
|
||||
'~': '__jest__/src',
|
||||
'@': '__jest__/src'
|
||||
},
|
||||
extensions: [
|
||||
'.ios.ts',
|
||||
'.ts',
|
||||
'.ios.js',
|
||||
'.js',
|
||||
'.ios.css',
|
||||
'.css',
|
||||
'.ios.scss',
|
||||
'.scss',
|
||||
'.ios.json',
|
||||
'.json'
|
||||
],
|
||||
mainFields: [
|
||||
'module',
|
||||
'main'
|
||||
],
|
||||
modules: [
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
resolveLoader: {
|
||||
modules: [
|
||||
'__jest__/node_modules/@nativescript/webpack/dist/loaders',
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
/* config.module.rule('bundle') */
|
||||
{
|
||||
enforce: 'post',
|
||||
test: '__jest__/src/app.js',
|
||||
use: [
|
||||
/* config.module.rule('bundle').use('app-css-loader') */
|
||||
{
|
||||
loader: 'app-css-loader',
|
||||
options: {
|
||||
platform: 'ios'
|
||||
}
|
||||
},
|
||||
/* config.module.rule('bundle').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
injectHMRRuntime: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('workers') */
|
||||
{
|
||||
test: /\\\\.(js|ts)$/,
|
||||
exclude: [
|
||||
/node_modules/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('workers').use('nativescript-worker-loader') */
|
||||
{
|
||||
loader: 'nativescript-worker-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('css') */
|
||||
{
|
||||
test: /\\\\.css$/,
|
||||
exclude: [
|
||||
/\\\\.component\\\\.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('css').use('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('scss') */
|
||||
{
|
||||
test: /\\\\.scss$/,
|
||||
exclude: [
|
||||
/\\\\.component\\\\.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('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
/* 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'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('css|component') */
|
||||
{
|
||||
test: /\\\\.component\\\\.css$/,
|
||||
use: [
|
||||
/* config.module.rule('css|component').use('raw-loader') */
|
||||
{
|
||||
loader: 'raw-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('scss|component') */
|
||||
{
|
||||
test: /\\\\.component\\\\.scss$/,
|
||||
use: [
|
||||
/* config.module.rule('scss|component').use('raw-loader') */
|
||||
{
|
||||
loader: 'raw-loader'
|
||||
},
|
||||
/* config.module.rule('scss|component').use('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
/* config.module.rule('scss|component').use('sass-loader') */
|
||||
{
|
||||
loader: 'sass-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_infinity: true,
|
||||
drop_console: false,
|
||||
global_defs: {
|
||||
__UGLIFIED__: true
|
||||
}
|
||||
},
|
||||
keep_fnames: true,
|
||||
keep_classnames: true
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
/* config.plugin('PlatformSuffixPlugin') */
|
||||
new PlatformSuffixPlugin(
|
||||
{
|
||||
platform: 'ios'
|
||||
}
|
||||
),
|
||||
/* config.plugin('ContextExclusionPlugin|App_Resources') */
|
||||
new ContextExclusionPlugin(
|
||||
/(.*)App_Resources(.*)/
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__NS_ENV_VERBOSE__: false,
|
||||
__NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]',
|
||||
__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,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: 'fonts/**',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: '**/*.+(jpg|png)',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
),
|
||||
/* 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/inspector_modules': [
|
||||
'@nativescript/core/inspector_modules'
|
||||
]
|
||||
}
|
||||
}"
|
||||
`;
|
@ -0,0 +1,604 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`base configuration for android 1`] = `
|
||||
"{
|
||||
mode: 'development',
|
||||
externals: [
|
||||
'package.json',
|
||||
'~/package.json'
|
||||
],
|
||||
devtool: 'inline-source-map',
|
||||
target: 'node',
|
||||
watchOptions: {
|
||||
ignored: [
|
||||
'__jest__/platforms/**',
|
||||
'__jest__/App_Resources/**'
|
||||
]
|
||||
},
|
||||
ignoreWarnings: [
|
||||
/System.import\\\\(\\\\) is deprecated/
|
||||
],
|
||||
output: {
|
||||
path: '__jest__/platforms/android/app/src/main/assets/app',
|
||||
pathinfo: false,
|
||||
publicPath: '',
|
||||
libraryTarget: 'commonjs',
|
||||
globalObject: 'global',
|
||||
clean: true
|
||||
},
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
alias: {
|
||||
'~': '__jest__/src',
|
||||
'@': '__jest__/src'
|
||||
},
|
||||
extensions: [
|
||||
'.android.ts',
|
||||
'.ts',
|
||||
'.android.js',
|
||||
'.js',
|
||||
'.android.css',
|
||||
'.css',
|
||||
'.android.scss',
|
||||
'.scss',
|
||||
'.android.json',
|
||||
'.json'
|
||||
],
|
||||
modules: [
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
resolveLoader: {
|
||||
modules: [
|
||||
'__jest__/node_modules/@nativescript/webpack/dist/loaders',
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
/* config.module.rule('bundle') */
|
||||
{
|
||||
enforce: 'post',
|
||||
test: '__jest__/src/app.js',
|
||||
use: [
|
||||
/* config.module.rule('bundle').use('app-css-loader') */
|
||||
{
|
||||
loader: 'app-css-loader',
|
||||
options: {
|
||||
platform: 'android'
|
||||
}
|
||||
},
|
||||
/* config.module.rule('bundle').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
injectHMRRuntime: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('ts') */
|
||||
{
|
||||
test: [
|
||||
/\\\\.ts$/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('ts').use('ts-loader') */
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true,
|
||||
allowTsInNodeModules: true,
|
||||
compilerOptions: {
|
||||
sourceMap: true,
|
||||
declaration: false
|
||||
},
|
||||
getCustomTransformers: function () { /* omitted long function */ }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('workers') */
|
||||
{
|
||||
test: /\\\\.(js|ts)$/,
|
||||
exclude: [
|
||||
/node_modules/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('workers').use('nativescript-worker-loader') */
|
||||
{
|
||||
loader: 'nativescript-worker-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('css').use('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
/* config.module.rule('scss').use('sass-loader') */
|
||||
{
|
||||
loader: 'sass-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_infinity: true,
|
||||
drop_console: false,
|
||||
global_defs: {
|
||||
__UGLIFIED__: true
|
||||
}
|
||||
},
|
||||
keep_fnames: true,
|
||||
keep_classnames: true
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
/* config.plugin('ForkTsCheckerWebpackPlugin') */
|
||||
new ForkTsCheckerWebpackPlugin(
|
||||
{
|
||||
typescript: {
|
||||
memoryLimit: 4096
|
||||
}
|
||||
}
|
||||
),
|
||||
/* config.plugin('PlatformSuffixPlugin') */
|
||||
new PlatformSuffixPlugin(
|
||||
{
|
||||
platform: 'android'
|
||||
}
|
||||
),
|
||||
/* config.plugin('ContextExclusionPlugin|App_Resources') */
|
||||
new ContextExclusionPlugin(
|
||||
/(.*)App_Resources(.*)/
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__NS_ENV_VERBOSE__: false,
|
||||
__NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]',
|
||||
__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,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: 'fonts/**',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: '**/*.+(jpg|png)',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
),
|
||||
/* config.plugin('WatchStatePlugin') */
|
||||
new WatchStatePlugin()
|
||||
],
|
||||
entry: {
|
||||
bundle: [
|
||||
'@nativescript/core/globals/index.js',
|
||||
'__jest__/src/app.js',
|
||||
'@nativescript/core/ui/frame',
|
||||
'@nativescript/core/ui/frame/activity'
|
||||
]
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`base configuration for ios 1`] = `
|
||||
"{
|
||||
mode: 'development',
|
||||
externals: [
|
||||
'package.json',
|
||||
'~/package.json'
|
||||
],
|
||||
devtool: 'inline-source-map',
|
||||
target: 'node',
|
||||
watchOptions: {
|
||||
ignored: [
|
||||
'__jest__/platforms/**',
|
||||
'__jest__/App_Resources/**'
|
||||
]
|
||||
},
|
||||
ignoreWarnings: [
|
||||
/System.import\\\\(\\\\) is deprecated/
|
||||
],
|
||||
output: {
|
||||
path: '__jest__/platforms/ios/jest/app',
|
||||
pathinfo: false,
|
||||
publicPath: '',
|
||||
libraryTarget: 'commonjs',
|
||||
globalObject: 'global',
|
||||
clean: true
|
||||
},
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
alias: {
|
||||
'~': '__jest__/src',
|
||||
'@': '__jest__/src'
|
||||
},
|
||||
extensions: [
|
||||
'.ios.ts',
|
||||
'.ts',
|
||||
'.ios.js',
|
||||
'.js',
|
||||
'.ios.css',
|
||||
'.css',
|
||||
'.ios.scss',
|
||||
'.scss',
|
||||
'.ios.json',
|
||||
'.json'
|
||||
],
|
||||
modules: [
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
resolveLoader: {
|
||||
modules: [
|
||||
'__jest__/node_modules/@nativescript/webpack/dist/loaders',
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
/* config.module.rule('bundle') */
|
||||
{
|
||||
enforce: 'post',
|
||||
test: '__jest__/src/app.js',
|
||||
use: [
|
||||
/* config.module.rule('bundle').use('app-css-loader') */
|
||||
{
|
||||
loader: 'app-css-loader',
|
||||
options: {
|
||||
platform: 'ios'
|
||||
}
|
||||
},
|
||||
/* config.module.rule('bundle').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
injectHMRRuntime: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('ts') */
|
||||
{
|
||||
test: [
|
||||
/\\\\.ts$/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('ts').use('ts-loader') */
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true,
|
||||
allowTsInNodeModules: true,
|
||||
compilerOptions: {
|
||||
sourceMap: true,
|
||||
declaration: false
|
||||
},
|
||||
getCustomTransformers: function () { /* omitted long function */ }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('workers') */
|
||||
{
|
||||
test: /\\\\.(js|ts)$/,
|
||||
exclude: [
|
||||
/node_modules/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('workers').use('nativescript-worker-loader') */
|
||||
{
|
||||
loader: 'nativescript-worker-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('css').use('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
/* config.module.rule('scss').use('sass-loader') */
|
||||
{
|
||||
loader: 'sass-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_infinity: true,
|
||||
drop_console: false,
|
||||
global_defs: {
|
||||
__UGLIFIED__: true
|
||||
}
|
||||
},
|
||||
keep_fnames: true,
|
||||
keep_classnames: true
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
/* config.plugin('ForkTsCheckerWebpackPlugin') */
|
||||
new ForkTsCheckerWebpackPlugin(
|
||||
{
|
||||
typescript: {
|
||||
memoryLimit: 4096
|
||||
}
|
||||
}
|
||||
),
|
||||
/* config.plugin('PlatformSuffixPlugin') */
|
||||
new PlatformSuffixPlugin(
|
||||
{
|
||||
platform: 'ios'
|
||||
}
|
||||
),
|
||||
/* config.plugin('ContextExclusionPlugin|App_Resources') */
|
||||
new ContextExclusionPlugin(
|
||||
/(.*)App_Resources(.*)/
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__NS_ENV_VERBOSE__: false,
|
||||
__NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]',
|
||||
__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,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: 'fonts/**',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: '**/*.+(jpg|png)',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
),
|
||||
/* config.plugin('WatchStatePlugin') */
|
||||
new WatchStatePlugin()
|
||||
],
|
||||
entry: {
|
||||
bundle: [
|
||||
'@nativescript/core/globals/index.js',
|
||||
'__jest__/src/app.js'
|
||||
],
|
||||
'tns_modules/inspector_modules': [
|
||||
'@nativescript/core/inspector_modules'
|
||||
]
|
||||
}
|
||||
}"
|
||||
`;
|
@ -0,0 +1,680 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`javascript configuration for android 1`] = `
|
||||
"{
|
||||
mode: 'development',
|
||||
externals: [
|
||||
'package.json',
|
||||
'~/package.json'
|
||||
],
|
||||
devtool: 'inline-source-map',
|
||||
target: 'node',
|
||||
watchOptions: {
|
||||
ignored: [
|
||||
'__jest__/platforms/**',
|
||||
'__jest__/App_Resources/**'
|
||||
]
|
||||
},
|
||||
ignoreWarnings: [
|
||||
/System.import\\\\(\\\\) is deprecated/
|
||||
],
|
||||
output: {
|
||||
path: '__jest__/platforms/android/app/src/main/assets/app',
|
||||
pathinfo: false,
|
||||
publicPath: '',
|
||||
libraryTarget: 'commonjs',
|
||||
globalObject: 'global',
|
||||
clean: true
|
||||
},
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
alias: {
|
||||
'~': '__jest__/src',
|
||||
'@': '__jest__/src'
|
||||
},
|
||||
extensions: [
|
||||
'.android.ts',
|
||||
'.ts',
|
||||
'.android.js',
|
||||
'.js',
|
||||
'.android.css',
|
||||
'.css',
|
||||
'.android.scss',
|
||||
'.scss',
|
||||
'.android.json',
|
||||
'.json'
|
||||
],
|
||||
modules: [
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
resolveLoader: {
|
||||
modules: [
|
||||
'__jest__/node_modules/@nativescript/webpack/dist/loaders',
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
/* config.module.rule('bundle') */
|
||||
{
|
||||
enforce: 'post',
|
||||
test: '__jest__/src/app.js',
|
||||
use: [
|
||||
/* config.module.rule('bundle').use('app-css-loader') */
|
||||
{
|
||||
loader: 'app-css-loader',
|
||||
options: {
|
||||
platform: 'android'
|
||||
}
|
||||
},
|
||||
/* config.module.rule('bundle').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
injectHMRRuntime: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('ts') */
|
||||
{
|
||||
test: [
|
||||
/\\\\.ts$/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('ts').use('ts-loader') */
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true,
|
||||
allowTsInNodeModules: true,
|
||||
compilerOptions: {
|
||||
sourceMap: true,
|
||||
declaration: false
|
||||
},
|
||||
getCustomTransformers: function () { /* omitted long function */ }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('workers') */
|
||||
{
|
||||
test: /\\\\.(js|ts)$/,
|
||||
exclude: [
|
||||
/node_modules/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('workers').use('nativescript-worker-loader') */
|
||||
{
|
||||
loader: 'nativescript-worker-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('css').use('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
/* config.module.rule('scss').use('sass-loader') */
|
||||
{
|
||||
loader: 'sass-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('xml') */
|
||||
{
|
||||
test: /\\\\.xml$/,
|
||||
use: [
|
||||
/* config.module.rule('xml').use('xml-namespace-loader') */
|
||||
{
|
||||
loader: 'xml-namespace-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('hmr-core') */
|
||||
{
|
||||
test: /\\\\.js$/,
|
||||
exclude: [
|
||||
/node_modules/,
|
||||
'__jest__/src/app.js'
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('hmr-core').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
appPath: '__jest__/src'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
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_infinity: true,
|
||||
drop_console: false,
|
||||
global_defs: {
|
||||
__UGLIFIED__: true
|
||||
}
|
||||
},
|
||||
keep_fnames: true,
|
||||
keep_classnames: true
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
/* config.plugin('ForkTsCheckerWebpackPlugin') */
|
||||
new ForkTsCheckerWebpackPlugin(
|
||||
{
|
||||
typescript: {
|
||||
memoryLimit: 4096
|
||||
}
|
||||
}
|
||||
),
|
||||
/* config.plugin('PlatformSuffixPlugin') */
|
||||
new PlatformSuffixPlugin(
|
||||
{
|
||||
platform: 'android'
|
||||
}
|
||||
),
|
||||
/* config.plugin('ContextExclusionPlugin|App_Resources') */
|
||||
new ContextExclusionPlugin(
|
||||
/(.*)App_Resources(.*)/
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__NS_ENV_VERBOSE__: false,
|
||||
__NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]',
|
||||
__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,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: 'fonts/**',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: '**/*.+(jpg|png)',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
),
|
||||
/* config.plugin('WatchStatePlugin') */
|
||||
new WatchStatePlugin(),
|
||||
/* config.plugin('ContextExclusionPlugin|__@nativescript_webpack_virtual_entry_javascript__') */
|
||||
new ContextExclusionPlugin(
|
||||
/__@nativescript_webpack_virtual_entry_javascript__.js$/
|
||||
),
|
||||
/* config.plugin('VirtualModulesPlugin') */
|
||||
new VirtualModulesPlugin(
|
||||
{
|
||||
'__jest__/src/__@nativescript_webpack_virtual_entry_javascript__': '// VIRTUAL ENTRY START\\\\nrequire(\\\\'@nativescript/core/bundle-entry-points\\\\')\\\\nconst context = require.context(\\"~/\\", /* deep: */ true, /* filter: */ /.(xml|js|s?css)$/);\\\\nglobal.registerWebpackModules(context);\\\\n// VIRTUAL ENTRY END'
|
||||
}
|
||||
)
|
||||
],
|
||||
entry: {
|
||||
bundle: [
|
||||
'@nativescript/core/globals/index.js',
|
||||
'__jest__/src/app.js',
|
||||
'@nativescript/core/ui/frame',
|
||||
'@nativescript/core/ui/frame/activity',
|
||||
'__jest__/src/__@nativescript_webpack_virtual_entry_javascript__'
|
||||
]
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`javascript configuration for ios 1`] = `
|
||||
"{
|
||||
mode: 'development',
|
||||
externals: [
|
||||
'package.json',
|
||||
'~/package.json'
|
||||
],
|
||||
devtool: 'inline-source-map',
|
||||
target: 'node',
|
||||
watchOptions: {
|
||||
ignored: [
|
||||
'__jest__/platforms/**',
|
||||
'__jest__/App_Resources/**'
|
||||
]
|
||||
},
|
||||
ignoreWarnings: [
|
||||
/System.import\\\\(\\\\) is deprecated/
|
||||
],
|
||||
output: {
|
||||
path: '__jest__/platforms/ios/jest/app',
|
||||
pathinfo: false,
|
||||
publicPath: '',
|
||||
libraryTarget: 'commonjs',
|
||||
globalObject: 'global',
|
||||
clean: true
|
||||
},
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
alias: {
|
||||
'~': '__jest__/src',
|
||||
'@': '__jest__/src'
|
||||
},
|
||||
extensions: [
|
||||
'.ios.ts',
|
||||
'.ts',
|
||||
'.ios.js',
|
||||
'.js',
|
||||
'.ios.css',
|
||||
'.css',
|
||||
'.ios.scss',
|
||||
'.scss',
|
||||
'.ios.json',
|
||||
'.json'
|
||||
],
|
||||
modules: [
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
resolveLoader: {
|
||||
modules: [
|
||||
'__jest__/node_modules/@nativescript/webpack/dist/loaders',
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
/* config.module.rule('bundle') */
|
||||
{
|
||||
enforce: 'post',
|
||||
test: '__jest__/src/app.js',
|
||||
use: [
|
||||
/* config.module.rule('bundle').use('app-css-loader') */
|
||||
{
|
||||
loader: 'app-css-loader',
|
||||
options: {
|
||||
platform: 'ios'
|
||||
}
|
||||
},
|
||||
/* config.module.rule('bundle').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
injectHMRRuntime: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('ts') */
|
||||
{
|
||||
test: [
|
||||
/\\\\.ts$/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('ts').use('ts-loader') */
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true,
|
||||
allowTsInNodeModules: true,
|
||||
compilerOptions: {
|
||||
sourceMap: true,
|
||||
declaration: false
|
||||
},
|
||||
getCustomTransformers: function () { /* omitted long function */ }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('workers') */
|
||||
{
|
||||
test: /\\\\.(js|ts)$/,
|
||||
exclude: [
|
||||
/node_modules/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('workers').use('nativescript-worker-loader') */
|
||||
{
|
||||
loader: 'nativescript-worker-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('css').use('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
/* config.module.rule('scss').use('sass-loader') */
|
||||
{
|
||||
loader: 'sass-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('xml') */
|
||||
{
|
||||
test: /\\\\.xml$/,
|
||||
use: [
|
||||
/* config.module.rule('xml').use('xml-namespace-loader') */
|
||||
{
|
||||
loader: 'xml-namespace-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('hmr-core') */
|
||||
{
|
||||
test: /\\\\.js$/,
|
||||
exclude: [
|
||||
/node_modules/,
|
||||
'__jest__/src/app.js'
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('hmr-core').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
appPath: '__jest__/src'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
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_infinity: true,
|
||||
drop_console: false,
|
||||
global_defs: {
|
||||
__UGLIFIED__: true
|
||||
}
|
||||
},
|
||||
keep_fnames: true,
|
||||
keep_classnames: true
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
/* config.plugin('ForkTsCheckerWebpackPlugin') */
|
||||
new ForkTsCheckerWebpackPlugin(
|
||||
{
|
||||
typescript: {
|
||||
memoryLimit: 4096
|
||||
}
|
||||
}
|
||||
),
|
||||
/* config.plugin('PlatformSuffixPlugin') */
|
||||
new PlatformSuffixPlugin(
|
||||
{
|
||||
platform: 'ios'
|
||||
}
|
||||
),
|
||||
/* config.plugin('ContextExclusionPlugin|App_Resources') */
|
||||
new ContextExclusionPlugin(
|
||||
/(.*)App_Resources(.*)/
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__NS_ENV_VERBOSE__: false,
|
||||
__NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]',
|
||||
__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,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: 'fonts/**',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: '**/*.+(jpg|png)',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
),
|
||||
/* config.plugin('WatchStatePlugin') */
|
||||
new WatchStatePlugin(),
|
||||
/* config.plugin('ContextExclusionPlugin|__@nativescript_webpack_virtual_entry_javascript__') */
|
||||
new ContextExclusionPlugin(
|
||||
/__@nativescript_webpack_virtual_entry_javascript__.js$/
|
||||
),
|
||||
/* config.plugin('VirtualModulesPlugin') */
|
||||
new VirtualModulesPlugin(
|
||||
{
|
||||
'__jest__/src/__@nativescript_webpack_virtual_entry_javascript__': '// VIRTUAL ENTRY START\\\\nrequire(\\\\'@nativescript/core/bundle-entry-points\\\\')\\\\nconst context = require.context(\\"~/\\", /* deep: */ true, /* filter: */ /.(xml|js|s?css)$/);\\\\nglobal.registerWebpackModules(context);\\\\n// VIRTUAL ENTRY END'
|
||||
}
|
||||
)
|
||||
],
|
||||
entry: {
|
||||
bundle: [
|
||||
'@nativescript/core/globals/index.js',
|
||||
'__jest__/src/app.js',
|
||||
'__jest__/src/__@nativescript_webpack_virtual_entry_javascript__'
|
||||
],
|
||||
'tns_modules/inspector_modules': [
|
||||
'@nativescript/core/inspector_modules'
|
||||
]
|
||||
}
|
||||
}"
|
||||
`;
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,654 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`svelte configuration for android 1`] = `
|
||||
"{
|
||||
mode: 'development',
|
||||
externals: [
|
||||
'package.json',
|
||||
'~/package.json'
|
||||
],
|
||||
devtool: 'inline-source-map',
|
||||
target: 'node',
|
||||
watchOptions: {
|
||||
ignored: [
|
||||
'__jest__/platforms/**',
|
||||
'__jest__/App_Resources/**'
|
||||
]
|
||||
},
|
||||
ignoreWarnings: [
|
||||
/System.import\\\\(\\\\) is deprecated/
|
||||
],
|
||||
output: {
|
||||
path: '__jest__/platforms/android/app/src/main/assets/app',
|
||||
pathinfo: false,
|
||||
publicPath: '',
|
||||
libraryTarget: 'commonjs',
|
||||
globalObject: 'global',
|
||||
clean: true
|
||||
},
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
alias: {
|
||||
'~': '__jest__/src',
|
||||
'@': '__jest__/src'
|
||||
},
|
||||
extensions: [
|
||||
'.android.svelte',
|
||||
'.svelte',
|
||||
'.android.ts',
|
||||
'.ts',
|
||||
'.android.js',
|
||||
'.js',
|
||||
'.android.css',
|
||||
'.css',
|
||||
'.android.scss',
|
||||
'.scss',
|
||||
'.android.json',
|
||||
'.json'
|
||||
],
|
||||
modules: [
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
resolveLoader: {
|
||||
modules: [
|
||||
'__jest__/node_modules/@nativescript/webpack/dist/loaders',
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
/* config.module.rule('bundle') */
|
||||
{
|
||||
enforce: 'post',
|
||||
test: '__jest__/src/app.js',
|
||||
use: [
|
||||
/* config.module.rule('bundle').use('app-css-loader') */
|
||||
{
|
||||
loader: 'app-css-loader',
|
||||
options: {
|
||||
platform: 'android'
|
||||
}
|
||||
},
|
||||
/* config.module.rule('bundle').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
injectHMRRuntime: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('ts') */
|
||||
{
|
||||
test: [
|
||||
/\\\\.ts$/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('ts').use('ts-loader') */
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true,
|
||||
allowTsInNodeModules: true,
|
||||
compilerOptions: {
|
||||
sourceMap: true,
|
||||
declaration: false
|
||||
},
|
||||
getCustomTransformers: function () { /* omitted long function */ }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('workers') */
|
||||
{
|
||||
test: /\\\\.(js|ts)$/,
|
||||
exclude: [
|
||||
/node_modules/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('workers').use('nativescript-worker-loader') */
|
||||
{
|
||||
loader: 'nativescript-worker-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('css').use('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
/* config.module.rule('scss').use('sass-loader') */
|
||||
{
|
||||
loader: 'sass-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('svelte') */
|
||||
{
|
||||
test: /\\\\.svelte$/,
|
||||
exclude: [
|
||||
/node_modules/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('svelte').use('svelte-loader-hot') */
|
||||
{
|
||||
loader: 'svelte-loader-hot',
|
||||
options: {
|
||||
dev: true,
|
||||
preprocess: undefined,
|
||||
hotReload: true,
|
||||
hotOptions: {
|
||||
injectCss: false,
|
||||
'native': true
|
||||
},
|
||||
onwarn: function () { /* omitted long function */ }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
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_infinity: true,
|
||||
drop_console: false,
|
||||
global_defs: {
|
||||
__UGLIFIED__: true
|
||||
}
|
||||
},
|
||||
keep_fnames: true,
|
||||
keep_classnames: true
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
/* config.plugin('ForkTsCheckerWebpackPlugin') */
|
||||
new ForkTsCheckerWebpackPlugin(
|
||||
{
|
||||
typescript: {
|
||||
memoryLimit: 4096
|
||||
}
|
||||
}
|
||||
),
|
||||
/* config.plugin('PlatformSuffixPlugin') */
|
||||
new PlatformSuffixPlugin(
|
||||
{
|
||||
platform: 'android'
|
||||
}
|
||||
),
|
||||
/* config.plugin('ContextExclusionPlugin|App_Resources') */
|
||||
new ContextExclusionPlugin(
|
||||
/(.*)App_Resources(.*)/
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__NS_ENV_VERBOSE__: false,
|
||||
__NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]',
|
||||
__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,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: 'fonts/**',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: '**/*.+(jpg|png)',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
),
|
||||
/* config.plugin('WatchStatePlugin') */
|
||||
new WatchStatePlugin()
|
||||
],
|
||||
entry: {
|
||||
bundle: [
|
||||
'@nativescript/core/globals/index.js',
|
||||
'__jest__/src/app.js',
|
||||
'@nativescript/core/ui/frame',
|
||||
'@nativescript/core/ui/frame/activity'
|
||||
]
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`svelte configuration for ios 1`] = `
|
||||
"{
|
||||
mode: 'development',
|
||||
externals: [
|
||||
'package.json',
|
||||
'~/package.json'
|
||||
],
|
||||
devtool: 'inline-source-map',
|
||||
target: 'node',
|
||||
watchOptions: {
|
||||
ignored: [
|
||||
'__jest__/platforms/**',
|
||||
'__jest__/App_Resources/**'
|
||||
]
|
||||
},
|
||||
ignoreWarnings: [
|
||||
/System.import\\\\(\\\\) is deprecated/
|
||||
],
|
||||
output: {
|
||||
path: '__jest__/platforms/ios/jest/app',
|
||||
pathinfo: false,
|
||||
publicPath: '',
|
||||
libraryTarget: 'commonjs',
|
||||
globalObject: 'global',
|
||||
clean: true
|
||||
},
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
alias: {
|
||||
'~': '__jest__/src',
|
||||
'@': '__jest__/src'
|
||||
},
|
||||
extensions: [
|
||||
'.ios.svelte',
|
||||
'.svelte',
|
||||
'.ios.ts',
|
||||
'.ts',
|
||||
'.ios.js',
|
||||
'.js',
|
||||
'.ios.css',
|
||||
'.css',
|
||||
'.ios.scss',
|
||||
'.scss',
|
||||
'.ios.json',
|
||||
'.json'
|
||||
],
|
||||
modules: [
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
resolveLoader: {
|
||||
modules: [
|
||||
'__jest__/node_modules/@nativescript/webpack/dist/loaders',
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
/* config.module.rule('bundle') */
|
||||
{
|
||||
enforce: 'post',
|
||||
test: '__jest__/src/app.js',
|
||||
use: [
|
||||
/* config.module.rule('bundle').use('app-css-loader') */
|
||||
{
|
||||
loader: 'app-css-loader',
|
||||
options: {
|
||||
platform: 'ios'
|
||||
}
|
||||
},
|
||||
/* config.module.rule('bundle').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
injectHMRRuntime: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('ts') */
|
||||
{
|
||||
test: [
|
||||
/\\\\.ts$/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('ts').use('ts-loader') */
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true,
|
||||
allowTsInNodeModules: true,
|
||||
compilerOptions: {
|
||||
sourceMap: true,
|
||||
declaration: false
|
||||
},
|
||||
getCustomTransformers: function () { /* omitted long function */ }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('workers') */
|
||||
{
|
||||
test: /\\\\.(js|ts)$/,
|
||||
exclude: [
|
||||
/node_modules/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('workers').use('nativescript-worker-loader') */
|
||||
{
|
||||
loader: 'nativescript-worker-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('css').use('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
/* config.module.rule('scss').use('sass-loader') */
|
||||
{
|
||||
loader: 'sass-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('svelte') */
|
||||
{
|
||||
test: /\\\\.svelte$/,
|
||||
exclude: [
|
||||
/node_modules/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('svelte').use('svelte-loader-hot') */
|
||||
{
|
||||
loader: 'svelte-loader-hot',
|
||||
options: {
|
||||
dev: true,
|
||||
preprocess: undefined,
|
||||
hotReload: true,
|
||||
hotOptions: {
|
||||
injectCss: false,
|
||||
'native': true
|
||||
},
|
||||
onwarn: function () { /* omitted long function */ }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
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_infinity: true,
|
||||
drop_console: false,
|
||||
global_defs: {
|
||||
__UGLIFIED__: true
|
||||
}
|
||||
},
|
||||
keep_fnames: true,
|
||||
keep_classnames: true
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
/* config.plugin('ForkTsCheckerWebpackPlugin') */
|
||||
new ForkTsCheckerWebpackPlugin(
|
||||
{
|
||||
typescript: {
|
||||
memoryLimit: 4096
|
||||
}
|
||||
}
|
||||
),
|
||||
/* config.plugin('PlatformSuffixPlugin') */
|
||||
new PlatformSuffixPlugin(
|
||||
{
|
||||
platform: 'ios'
|
||||
}
|
||||
),
|
||||
/* config.plugin('ContextExclusionPlugin|App_Resources') */
|
||||
new ContextExclusionPlugin(
|
||||
/(.*)App_Resources(.*)/
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__NS_ENV_VERBOSE__: false,
|
||||
__NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]',
|
||||
__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,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: 'fonts/**',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: '**/*.+(jpg|png)',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
),
|
||||
/* config.plugin('WatchStatePlugin') */
|
||||
new WatchStatePlugin()
|
||||
],
|
||||
entry: {
|
||||
bundle: [
|
||||
'@nativescript/core/globals/index.js',
|
||||
'__jest__/src/app.js'
|
||||
],
|
||||
'tns_modules/inspector_modules': [
|
||||
'@nativescript/core/inspector_modules'
|
||||
]
|
||||
}
|
||||
}"
|
||||
`;
|
@ -0,0 +1,680 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`typescript configuration for android 1`] = `
|
||||
"{
|
||||
mode: 'development',
|
||||
externals: [
|
||||
'package.json',
|
||||
'~/package.json'
|
||||
],
|
||||
devtool: 'inline-source-map',
|
||||
target: 'node',
|
||||
watchOptions: {
|
||||
ignored: [
|
||||
'__jest__/platforms/**',
|
||||
'__jest__/App_Resources/**'
|
||||
]
|
||||
},
|
||||
ignoreWarnings: [
|
||||
/System.import\\\\(\\\\) is deprecated/
|
||||
],
|
||||
output: {
|
||||
path: '__jest__/platforms/android/app/src/main/assets/app',
|
||||
pathinfo: false,
|
||||
publicPath: '',
|
||||
libraryTarget: 'commonjs',
|
||||
globalObject: 'global',
|
||||
clean: true
|
||||
},
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
alias: {
|
||||
'~': '__jest__/src',
|
||||
'@': '__jest__/src'
|
||||
},
|
||||
extensions: [
|
||||
'.android.ts',
|
||||
'.ts',
|
||||
'.android.js',
|
||||
'.js',
|
||||
'.android.css',
|
||||
'.css',
|
||||
'.android.scss',
|
||||
'.scss',
|
||||
'.android.json',
|
||||
'.json'
|
||||
],
|
||||
modules: [
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
resolveLoader: {
|
||||
modules: [
|
||||
'__jest__/node_modules/@nativescript/webpack/dist/loaders',
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
/* config.module.rule('bundle') */
|
||||
{
|
||||
enforce: 'post',
|
||||
test: '__jest__/src/app.js',
|
||||
use: [
|
||||
/* config.module.rule('bundle').use('app-css-loader') */
|
||||
{
|
||||
loader: 'app-css-loader',
|
||||
options: {
|
||||
platform: 'android'
|
||||
}
|
||||
},
|
||||
/* config.module.rule('bundle').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
injectHMRRuntime: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('ts') */
|
||||
{
|
||||
test: [
|
||||
/\\\\.ts$/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('ts').use('ts-loader') */
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true,
|
||||
allowTsInNodeModules: true,
|
||||
compilerOptions: {
|
||||
sourceMap: true,
|
||||
declaration: false
|
||||
},
|
||||
getCustomTransformers: function () { /* omitted long function */ }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('workers') */
|
||||
{
|
||||
test: /\\\\.(js|ts)$/,
|
||||
exclude: [
|
||||
/node_modules/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('workers').use('nativescript-worker-loader') */
|
||||
{
|
||||
loader: 'nativescript-worker-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('css').use('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
/* config.module.rule('scss').use('sass-loader') */
|
||||
{
|
||||
loader: 'sass-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('xml') */
|
||||
{
|
||||
test: /\\\\.xml$/,
|
||||
use: [
|
||||
/* config.module.rule('xml').use('xml-namespace-loader') */
|
||||
{
|
||||
loader: 'xml-namespace-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('hmr-core') */
|
||||
{
|
||||
test: /\\\\.(js|ts)$/,
|
||||
exclude: [
|
||||
/node_modules/,
|
||||
'__jest__/src/app.js'
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('hmr-core').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
appPath: '__jest__/src'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
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_infinity: true,
|
||||
drop_console: false,
|
||||
global_defs: {
|
||||
__UGLIFIED__: true
|
||||
}
|
||||
},
|
||||
keep_fnames: true,
|
||||
keep_classnames: true
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
/* config.plugin('ForkTsCheckerWebpackPlugin') */
|
||||
new ForkTsCheckerWebpackPlugin(
|
||||
{
|
||||
typescript: {
|
||||
memoryLimit: 4096
|
||||
}
|
||||
}
|
||||
),
|
||||
/* config.plugin('PlatformSuffixPlugin') */
|
||||
new PlatformSuffixPlugin(
|
||||
{
|
||||
platform: 'android'
|
||||
}
|
||||
),
|
||||
/* config.plugin('ContextExclusionPlugin|App_Resources') */
|
||||
new ContextExclusionPlugin(
|
||||
/(.*)App_Resources(.*)/
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__NS_ENV_VERBOSE__: false,
|
||||
__NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]',
|
||||
__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,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: 'fonts/**',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: '**/*.+(jpg|png)',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
),
|
||||
/* config.plugin('WatchStatePlugin') */
|
||||
new WatchStatePlugin(),
|
||||
/* config.plugin('ContextExclusionPlugin|__@nativescript_webpack_virtual_entry_typescript__') */
|
||||
new ContextExclusionPlugin(
|
||||
/__@nativescript_webpack_virtual_entry_typescript__.js$/
|
||||
),
|
||||
/* config.plugin('VirtualModulesPlugin') */
|
||||
new VirtualModulesPlugin(
|
||||
{
|
||||
'__jest__/src/__@nativescript_webpack_virtual_entry_typescript__': '// VIRTUAL ENTRY START\\\\nrequire(\\\\'@nativescript/core/bundle-entry-points\\\\')\\\\nconst context = require.context(\\"~/\\", /* deep: */ true, /* filter: */ /\\\\\\\\.(xml|js|(?<!d\\\\\\\\.)ts|s?css)$/);\\\\nglobal.registerWebpackModules(context);\\\\n// VIRTUAL ENTRY END'
|
||||
}
|
||||
)
|
||||
],
|
||||
entry: {
|
||||
bundle: [
|
||||
'@nativescript/core/globals/index.js',
|
||||
'__jest__/src/app.js',
|
||||
'@nativescript/core/ui/frame',
|
||||
'@nativescript/core/ui/frame/activity',
|
||||
'__jest__/src/__@nativescript_webpack_virtual_entry_typescript__'
|
||||
]
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`typescript configuration for ios 1`] = `
|
||||
"{
|
||||
mode: 'development',
|
||||
externals: [
|
||||
'package.json',
|
||||
'~/package.json'
|
||||
],
|
||||
devtool: 'inline-source-map',
|
||||
target: 'node',
|
||||
watchOptions: {
|
||||
ignored: [
|
||||
'__jest__/platforms/**',
|
||||
'__jest__/App_Resources/**'
|
||||
]
|
||||
},
|
||||
ignoreWarnings: [
|
||||
/System.import\\\\(\\\\) is deprecated/
|
||||
],
|
||||
output: {
|
||||
path: '__jest__/platforms/ios/jest/app',
|
||||
pathinfo: false,
|
||||
publicPath: '',
|
||||
libraryTarget: 'commonjs',
|
||||
globalObject: 'global',
|
||||
clean: true
|
||||
},
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
alias: {
|
||||
'~': '__jest__/src',
|
||||
'@': '__jest__/src'
|
||||
},
|
||||
extensions: [
|
||||
'.ios.ts',
|
||||
'.ts',
|
||||
'.ios.js',
|
||||
'.js',
|
||||
'.ios.css',
|
||||
'.css',
|
||||
'.ios.scss',
|
||||
'.scss',
|
||||
'.ios.json',
|
||||
'.json'
|
||||
],
|
||||
modules: [
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
resolveLoader: {
|
||||
modules: [
|
||||
'__jest__/node_modules/@nativescript/webpack/dist/loaders',
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
/* config.module.rule('bundle') */
|
||||
{
|
||||
enforce: 'post',
|
||||
test: '__jest__/src/app.js',
|
||||
use: [
|
||||
/* config.module.rule('bundle').use('app-css-loader') */
|
||||
{
|
||||
loader: 'app-css-loader',
|
||||
options: {
|
||||
platform: 'ios'
|
||||
}
|
||||
},
|
||||
/* config.module.rule('bundle').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
injectHMRRuntime: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('ts') */
|
||||
{
|
||||
test: [
|
||||
/\\\\.ts$/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('ts').use('ts-loader') */
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true,
|
||||
allowTsInNodeModules: true,
|
||||
compilerOptions: {
|
||||
sourceMap: true,
|
||||
declaration: false
|
||||
},
|
||||
getCustomTransformers: function () { /* omitted long function */ }
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('workers') */
|
||||
{
|
||||
test: /\\\\.(js|ts)$/,
|
||||
exclude: [
|
||||
/node_modules/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('workers').use('nativescript-worker-loader') */
|
||||
{
|
||||
loader: 'nativescript-worker-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('css').use('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
/* config.module.rule('scss').use('sass-loader') */
|
||||
{
|
||||
loader: 'sass-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('xml') */
|
||||
{
|
||||
test: /\\\\.xml$/,
|
||||
use: [
|
||||
/* config.module.rule('xml').use('xml-namespace-loader') */
|
||||
{
|
||||
loader: 'xml-namespace-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('hmr-core') */
|
||||
{
|
||||
test: /\\\\.(js|ts)$/,
|
||||
exclude: [
|
||||
/node_modules/,
|
||||
'__jest__/src/app.js'
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('hmr-core').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
appPath: '__jest__/src'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
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_infinity: true,
|
||||
drop_console: false,
|
||||
global_defs: {
|
||||
__UGLIFIED__: true
|
||||
}
|
||||
},
|
||||
keep_fnames: true,
|
||||
keep_classnames: true
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
/* config.plugin('ForkTsCheckerWebpackPlugin') */
|
||||
new ForkTsCheckerWebpackPlugin(
|
||||
{
|
||||
typescript: {
|
||||
memoryLimit: 4096
|
||||
}
|
||||
}
|
||||
),
|
||||
/* config.plugin('PlatformSuffixPlugin') */
|
||||
new PlatformSuffixPlugin(
|
||||
{
|
||||
platform: 'ios'
|
||||
}
|
||||
),
|
||||
/* config.plugin('ContextExclusionPlugin|App_Resources') */
|
||||
new ContextExclusionPlugin(
|
||||
/(.*)App_Resources(.*)/
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__NS_ENV_VERBOSE__: false,
|
||||
__NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]',
|
||||
__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,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: 'fonts/**',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: '**/*.+(jpg|png)',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
),
|
||||
/* config.plugin('WatchStatePlugin') */
|
||||
new WatchStatePlugin(),
|
||||
/* config.plugin('ContextExclusionPlugin|__@nativescript_webpack_virtual_entry_typescript__') */
|
||||
new ContextExclusionPlugin(
|
||||
/__@nativescript_webpack_virtual_entry_typescript__.js$/
|
||||
),
|
||||
/* config.plugin('VirtualModulesPlugin') */
|
||||
new VirtualModulesPlugin(
|
||||
{
|
||||
'__jest__/src/__@nativescript_webpack_virtual_entry_typescript__': '// VIRTUAL ENTRY START\\\\nrequire(\\\\'@nativescript/core/bundle-entry-points\\\\')\\\\nconst context = require.context(\\"~/\\", /* deep: */ true, /* filter: */ /\\\\\\\\.(xml|js|(?<!d\\\\\\\\.)ts|s?css)$/);\\\\nglobal.registerWebpackModules(context);\\\\n// VIRTUAL ENTRY END'
|
||||
}
|
||||
)
|
||||
],
|
||||
entry: {
|
||||
bundle: [
|
||||
'@nativescript/core/globals/index.js',
|
||||
'__jest__/src/app.js',
|
||||
'__jest__/src/__@nativescript_webpack_virtual_entry_typescript__'
|
||||
],
|
||||
'tns_modules/inspector_modules': [
|
||||
'@nativescript/core/inspector_modules'
|
||||
]
|
||||
}
|
||||
}"
|
||||
`;
|
@ -0,0 +1,668 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`vue configuration for android 1`] = `
|
||||
"{
|
||||
mode: 'development',
|
||||
externals: [
|
||||
'package.json',
|
||||
'~/package.json'
|
||||
],
|
||||
devtool: 'inline-source-map',
|
||||
target: 'node',
|
||||
watchOptions: {
|
||||
ignored: [
|
||||
'__jest__/platforms/**',
|
||||
'__jest__/App_Resources/**'
|
||||
]
|
||||
},
|
||||
ignoreWarnings: [
|
||||
/System.import\\\\(\\\\) is deprecated/
|
||||
],
|
||||
output: {
|
||||
path: '__jest__/platforms/android/app/src/main/assets/app',
|
||||
pathinfo: false,
|
||||
publicPath: '',
|
||||
libraryTarget: 'commonjs',
|
||||
globalObject: 'global',
|
||||
clean: true
|
||||
},
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
alias: {
|
||||
'~': '__jest__/src',
|
||||
'@': '__jest__/src',
|
||||
vue: 'nativescript-vue'
|
||||
},
|
||||
extensions: [
|
||||
'.android.vue',
|
||||
'.vue',
|
||||
'.android.ts',
|
||||
'.ts',
|
||||
'.android.js',
|
||||
'.js',
|
||||
'.android.css',
|
||||
'.css',
|
||||
'.android.scss',
|
||||
'.scss',
|
||||
'.android.json',
|
||||
'.json'
|
||||
],
|
||||
modules: [
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
resolveLoader: {
|
||||
modules: [
|
||||
'__jest__/node_modules/@nativescript/webpack/dist/loaders',
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
/* config.module.rule('bundle') */
|
||||
{
|
||||
enforce: 'post',
|
||||
test: '__jest__/src/app.js',
|
||||
use: [
|
||||
/* config.module.rule('bundle').use('app-css-loader') */
|
||||
{
|
||||
loader: 'app-css-loader',
|
||||
options: {
|
||||
platform: 'android'
|
||||
}
|
||||
},
|
||||
/* config.module.rule('bundle').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
injectHMRRuntime: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('ts') */
|
||||
{
|
||||
test: [
|
||||
/\\\\.ts$/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('ts').use('ts-loader') */
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true,
|
||||
allowTsInNodeModules: true,
|
||||
compilerOptions: {
|
||||
sourceMap: true,
|
||||
declaration: false
|
||||
},
|
||||
getCustomTransformers: function () { /* omitted long function */ },
|
||||
appendTsSuffixTo: [
|
||||
'\\\\\\\\.vue$'
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('workers') */
|
||||
{
|
||||
test: /\\\\.(js|ts)$/,
|
||||
exclude: [
|
||||
/node_modules/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('workers').use('nativescript-worker-loader') */
|
||||
{
|
||||
loader: 'nativescript-worker-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('css').use('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
/* config.module.rule('scss').use('sass-loader') */
|
||||
{
|
||||
loader: 'sass-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('vue') */
|
||||
{
|
||||
test: /\\\\.vue$/,
|
||||
use: [
|
||||
/* config.module.rule('vue').use('vue-loader') */
|
||||
{
|
||||
loader: 'vue-loader',
|
||||
options: {
|
||||
compiler: {
|
||||
compile: function () { /* omitted long function */ },
|
||||
compileToFunctions: function () { /* omitted long function */ },
|
||||
parseComponent: function () { /* omitted long function */ },
|
||||
registerElement: function () { /* omitted long function */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
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_infinity: true,
|
||||
drop_console: false,
|
||||
global_defs: {
|
||||
__UGLIFIED__: true
|
||||
}
|
||||
},
|
||||
keep_fnames: true,
|
||||
keep_classnames: true
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
/* config.plugin('VueLoaderPlugin') */
|
||||
new VueLoaderPlugin(),
|
||||
/* config.plugin('ForkTsCheckerWebpackPlugin') */
|
||||
new ForkTsCheckerWebpackPlugin(
|
||||
{
|
||||
typescript: {
|
||||
memoryLimit: 4096,
|
||||
extensions: {
|
||||
vue: {
|
||||
enabled: true,
|
||||
compiler: 'nativescript-vue-template-compiler'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
),
|
||||
/* config.plugin('PlatformSuffixPlugin') */
|
||||
new PlatformSuffixPlugin(
|
||||
{
|
||||
platform: 'android'
|
||||
}
|
||||
),
|
||||
/* config.plugin('ContextExclusionPlugin|App_Resources') */
|
||||
new ContextExclusionPlugin(
|
||||
/(.*)App_Resources(.*)/
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__NS_ENV_VERBOSE__: false,
|
||||
__NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]',
|
||||
__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,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: 'fonts/**',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: '**/*.+(jpg|png)',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
),
|
||||
/* config.plugin('WatchStatePlugin') */
|
||||
new WatchStatePlugin()
|
||||
],
|
||||
entry: {
|
||||
bundle: [
|
||||
'@nativescript/core/globals/index.js',
|
||||
'__jest__/src/app.js',
|
||||
'@nativescript/core/ui/frame',
|
||||
'@nativescript/core/ui/frame/activity'
|
||||
]
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`vue configuration for ios 1`] = `
|
||||
"{
|
||||
mode: 'development',
|
||||
externals: [
|
||||
'package.json',
|
||||
'~/package.json'
|
||||
],
|
||||
devtool: 'inline-source-map',
|
||||
target: 'node',
|
||||
watchOptions: {
|
||||
ignored: [
|
||||
'__jest__/platforms/**',
|
||||
'__jest__/App_Resources/**'
|
||||
]
|
||||
},
|
||||
ignoreWarnings: [
|
||||
/System.import\\\\(\\\\) is deprecated/
|
||||
],
|
||||
output: {
|
||||
path: '__jest__/platforms/ios/jest/app',
|
||||
pathinfo: false,
|
||||
publicPath: '',
|
||||
libraryTarget: 'commonjs',
|
||||
globalObject: 'global',
|
||||
clean: true
|
||||
},
|
||||
resolve: {
|
||||
symlinks: true,
|
||||
alias: {
|
||||
'~': '__jest__/src',
|
||||
'@': '__jest__/src',
|
||||
vue: 'nativescript-vue'
|
||||
},
|
||||
extensions: [
|
||||
'.ios.vue',
|
||||
'.vue',
|
||||
'.ios.ts',
|
||||
'.ts',
|
||||
'.ios.js',
|
||||
'.js',
|
||||
'.ios.css',
|
||||
'.css',
|
||||
'.ios.scss',
|
||||
'.scss',
|
||||
'.ios.json',
|
||||
'.json'
|
||||
],
|
||||
modules: [
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
resolveLoader: {
|
||||
modules: [
|
||||
'__jest__/node_modules/@nativescript/webpack/dist/loaders',
|
||||
'__jest__/node_modules',
|
||||
'node_modules'
|
||||
]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
/* config.module.rule('bundle') */
|
||||
{
|
||||
enforce: 'post',
|
||||
test: '__jest__/src/app.js',
|
||||
use: [
|
||||
/* config.module.rule('bundle').use('app-css-loader') */
|
||||
{
|
||||
loader: 'app-css-loader',
|
||||
options: {
|
||||
platform: 'ios'
|
||||
}
|
||||
},
|
||||
/* config.module.rule('bundle').use('nativescript-hot-loader') */
|
||||
{
|
||||
loader: 'nativescript-hot-loader',
|
||||
options: {
|
||||
injectHMRRuntime: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('ts') */
|
||||
{
|
||||
test: [
|
||||
/\\\\.ts$/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('ts').use('ts-loader') */
|
||||
{
|
||||
loader: 'ts-loader',
|
||||
options: {
|
||||
transpileOnly: true,
|
||||
allowTsInNodeModules: true,
|
||||
compilerOptions: {
|
||||
sourceMap: true,
|
||||
declaration: false
|
||||
},
|
||||
getCustomTransformers: function () { /* omitted long function */ },
|
||||
appendTsSuffixTo: [
|
||||
'\\\\\\\\.vue$'
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('workers') */
|
||||
{
|
||||
test: /\\\\.(js|ts)$/,
|
||||
exclude: [
|
||||
/node_modules/
|
||||
],
|
||||
use: [
|
||||
/* config.module.rule('workers').use('nativescript-worker-loader') */
|
||||
{
|
||||
loader: 'nativescript-worker-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('css').use('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
/* 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('postcss-loader') */
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
'postcss-import'
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
/* config.module.rule('scss').use('sass-loader') */
|
||||
{
|
||||
loader: 'sass-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
/* config.module.rule('vue') */
|
||||
{
|
||||
test: /\\\\.vue$/,
|
||||
use: [
|
||||
/* config.module.rule('vue').use('vue-loader') */
|
||||
{
|
||||
loader: 'vue-loader',
|
||||
options: {
|
||||
compiler: {
|
||||
compile: function () { /* omitted long function */ },
|
||||
compileToFunctions: function () { /* omitted long function */ },
|
||||
parseComponent: function () { /* omitted long function */ },
|
||||
registerElement: function () { /* omitted long function */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
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_infinity: true,
|
||||
drop_console: false,
|
||||
global_defs: {
|
||||
__UGLIFIED__: true
|
||||
}
|
||||
},
|
||||
keep_fnames: true,
|
||||
keep_classnames: true
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
/* config.plugin('VueLoaderPlugin') */
|
||||
new VueLoaderPlugin(),
|
||||
/* config.plugin('ForkTsCheckerWebpackPlugin') */
|
||||
new ForkTsCheckerWebpackPlugin(
|
||||
{
|
||||
typescript: {
|
||||
memoryLimit: 4096,
|
||||
extensions: {
|
||||
vue: {
|
||||
enabled: true,
|
||||
compiler: 'nativescript-vue-template-compiler'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
),
|
||||
/* config.plugin('PlatformSuffixPlugin') */
|
||||
new PlatformSuffixPlugin(
|
||||
{
|
||||
platform: 'ios'
|
||||
}
|
||||
),
|
||||
/* config.plugin('ContextExclusionPlugin|App_Resources') */
|
||||
new ContextExclusionPlugin(
|
||||
/(.*)App_Resources(.*)/
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__NS_ENV_VERBOSE__: false,
|
||||
__NS_DEV_HOST_IPS__: '[\\"127.0.0.1\\",\\"192.168.0.10\\"]',
|
||||
__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,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: 'fonts/**',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
},
|
||||
{
|
||||
from: '**/*.+(jpg|png)',
|
||||
context: '__jest__/src',
|
||||
noErrorOnMissing: true,
|
||||
globOptions: {
|
||||
dot: false,
|
||||
ignore: []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
),
|
||||
/* config.plugin('WatchStatePlugin') */
|
||||
new WatchStatePlugin()
|
||||
],
|
||||
entry: {
|
||||
bundle: [
|
||||
'@nativescript/core/globals/index.js',
|
||||
'__jest__/src/app.js'
|
||||
],
|
||||
'tns_modules/inspector_modules': [
|
||||
'@nativescript/core/inspector_modules'
|
||||
]
|
||||
}
|
||||
}"
|
||||
`;
|
49
packages/webpack5/__tests__/configuration/angular.spec.ts
Normal file
49
packages/webpack5/__tests__/configuration/angular.spec.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import Config from 'webpack-chain';
|
||||
import { resolve } from 'path';
|
||||
|
||||
import { additionalCopyRules } from '../../src/helpers/copyRules';
|
||||
import { default as angular } from '../../src/configuration/angular';
|
||||
import { init } from '../../src';
|
||||
|
||||
jest.mock(
|
||||
'@ngtools/webpack',
|
||||
() => {
|
||||
class AngularCompilerPlugin {}
|
||||
|
||||
return {
|
||||
AngularCompilerPlugin,
|
||||
};
|
||||
},
|
||||
{ virtual: true }
|
||||
);
|
||||
|
||||
describe('angular configuration', () => {
|
||||
const platforms = ['ios', 'android'];
|
||||
let fsExistsSyncSpy: jest.SpiedFunction<any>;
|
||||
|
||||
beforeAll(() => {
|
||||
const fs = require('fs');
|
||||
const original = fs.existsSync;
|
||||
fsExistsSyncSpy = jest.spyOn(fs, 'existsSync');
|
||||
|
||||
fsExistsSyncSpy.mockImplementation((path) => {
|
||||
if (path === '__jest__/tsconfig.json') {
|
||||
return true;
|
||||
}
|
||||
return original.call(fs, path);
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
fsExistsSyncSpy.mockRestore();
|
||||
});
|
||||
|
||||
for (let platform of platforms) {
|
||||
it(`for ${platform}`, () => {
|
||||
init({
|
||||
[platform]: true,
|
||||
});
|
||||
expect(angular(new Config()).toString()).toMatchSnapshot();
|
||||
});
|
||||
}
|
||||
});
|
103
packages/webpack5/__tests__/configuration/base.spec.ts
Normal file
103
packages/webpack5/__tests__/configuration/base.spec.ts
Normal file
@ -0,0 +1,103 @@
|
||||
import Config from 'webpack-chain';
|
||||
import fs from 'fs';
|
||||
|
||||
import base from '../../src/configuration/base';
|
||||
import { init } from '../../src';
|
||||
import { applyFileReplacements } from "../../src/helpers/fileReplacements";
|
||||
import { additionalCopyRules } from "../../src/helpers/copyRules";
|
||||
|
||||
describe('base configuration', () => {
|
||||
const platforms = ['ios', 'android'];
|
||||
|
||||
for (let platform of platforms) {
|
||||
it(`for ${platform}`, () => {
|
||||
init({
|
||||
[platform]: true,
|
||||
});
|
||||
expect(base(new Config()).toString()).toMatchSnapshot();
|
||||
});
|
||||
}
|
||||
|
||||
it('supports dotenv', () => {
|
||||
const fsSpy = jest.spyOn(fs, "existsSync")
|
||||
fsSpy.mockReturnValue(true)
|
||||
|
||||
init({
|
||||
ios: true,
|
||||
});
|
||||
const config = base(new Config());
|
||||
|
||||
expect(config.plugin('DotEnvPlugin')).toBeDefined();
|
||||
config.plugin('DotEnvPlugin').tap((args) => {
|
||||
expect(args[0].path).toEqual('__jest__/.env');
|
||||
return args;
|
||||
});
|
||||
|
||||
fsSpy.mockRestore()
|
||||
});
|
||||
|
||||
it('supports env specific dotenv', () => {
|
||||
const fsSpy = jest.spyOn(fs, "existsSync")
|
||||
fsSpy.mockReturnValue(true)
|
||||
|
||||
init({
|
||||
ios: true,
|
||||
env: 'prod',
|
||||
});
|
||||
const config = base(new Config());
|
||||
|
||||
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env.prod')
|
||||
expect(fsSpy).toHaveBeenCalledTimes(1)
|
||||
expect(config.plugin('DotEnvPlugin')).toBeDefined();
|
||||
config.plugin('DotEnvPlugin').tap((args) => {
|
||||
expect(args[0].path).toEqual('__jest__/.env.prod');
|
||||
return args;
|
||||
});
|
||||
fsSpy.mockRestore()
|
||||
});
|
||||
|
||||
it('falls back to default .env', () => {
|
||||
const fsSpy = jest.spyOn(fs, "existsSync")
|
||||
fsSpy
|
||||
.mockReturnValueOnce(false)
|
||||
.mockReturnValueOnce(true)
|
||||
|
||||
|
||||
init({
|
||||
ios: true,
|
||||
env: 'prod',
|
||||
});
|
||||
const config = base(new Config());
|
||||
|
||||
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env.prod')
|
||||
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env')
|
||||
expect(fsSpy).toHaveBeenCalledTimes(2)
|
||||
expect(config.plugin('DotEnvPlugin')).toBeDefined();
|
||||
config.plugin('DotEnvPlugin').tap((args) => {
|
||||
expect(args[0].path).toEqual('__jest__/.env');
|
||||
return args;
|
||||
});
|
||||
fsSpy.mockRestore()
|
||||
});
|
||||
|
||||
it('applies file replacements', () => {
|
||||
const config = new Config();
|
||||
applyFileReplacements(config, {
|
||||
// should apply as an alias
|
||||
'foo.ts': 'foo.replaced.ts',
|
||||
'bar.js': 'bar.replaced.js',
|
||||
|
||||
// should apply as a file replacement using the copy plugin
|
||||
'foo.json': 'foo.replaced.json'
|
||||
})
|
||||
|
||||
expect(config.resolve.alias.get('foo.ts')).toBe('foo.replaced.ts')
|
||||
expect(config.resolve.alias.get('bar.js')).toBe('bar.replaced.js')
|
||||
expect(additionalCopyRules.length).toBe(1)
|
||||
expect(additionalCopyRules[0]).toEqual({
|
||||
from: 'foo.replaced.json',
|
||||
to: 'foo.json',
|
||||
force: true,
|
||||
})
|
||||
})
|
||||
});
|
17
packages/webpack5/__tests__/configuration/javascript.spec.ts
Normal file
17
packages/webpack5/__tests__/configuration/javascript.spec.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import Config from 'webpack-chain';
|
||||
|
||||
import javascript from '../../src/configuration/javascript';
|
||||
import { init } from '../../src';
|
||||
|
||||
describe('javascript configuration', () => {
|
||||
const platforms = ['ios', 'android'];
|
||||
|
||||
for (let platform of platforms) {
|
||||
it(`for ${platform}`, () => {
|
||||
init({
|
||||
[platform]: true,
|
||||
});
|
||||
expect(javascript(new Config()).toString()).toMatchSnapshot();
|
||||
});
|
||||
}
|
||||
});
|
27
packages/webpack5/__tests__/configuration/react.spec.ts
Normal file
27
packages/webpack5/__tests__/configuration/react.spec.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import Config from 'webpack-chain';
|
||||
|
||||
import react from '../../src/configuration/react';
|
||||
import { init } from '../../src';
|
||||
|
||||
describe('react configuration', () => {
|
||||
const platforms = ['ios', 'android'];
|
||||
|
||||
for (let platform of platforms) {
|
||||
describe(`> ${platform} >`, () => {
|
||||
it(`base config`, () => {
|
||||
init({
|
||||
[platform]: true,
|
||||
});
|
||||
expect(react(new Config()).toString()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it(`adds ReactRefreshWebpackPlugin when HMR enabled`, () => {
|
||||
init({
|
||||
[platform]: true,
|
||||
hmr: true,
|
||||
});
|
||||
expect(react(new Config()).toString()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
21
packages/webpack5/__tests__/configuration/svelte.spec.ts
Normal file
21
packages/webpack5/__tests__/configuration/svelte.spec.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import Config from 'webpack-chain';
|
||||
|
||||
import svelte from '../../src/configuration/svelte';
|
||||
import { init } from '../../src';
|
||||
|
||||
jest.mock('__jest__/svelte.config.js', () => {
|
||||
|
||||
}, { virtual: true })
|
||||
|
||||
describe('svelte configuration', () => {
|
||||
const platforms = ['ios', 'android'];
|
||||
|
||||
for (let platform of platforms) {
|
||||
it(`for ${platform}`, () => {
|
||||
init({
|
||||
[platform]: true,
|
||||
});
|
||||
expect(svelte(new Config()).toString()).toMatchSnapshot();
|
||||
});
|
||||
}
|
||||
});
|
17
packages/webpack5/__tests__/configuration/typescript.spec.ts
Normal file
17
packages/webpack5/__tests__/configuration/typescript.spec.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import Config from 'webpack-chain';
|
||||
|
||||
import typescript from '../../src/configuration/typescript';
|
||||
import { init } from '../../src';
|
||||
|
||||
describe('typescript configuration', () => {
|
||||
const platforms = ['ios', 'android'];
|
||||
|
||||
for (let platform of platforms) {
|
||||
it(`for ${platform}`, () => {
|
||||
init({
|
||||
[platform]: true,
|
||||
});
|
||||
expect(typescript(new Config()).toString()).toMatchSnapshot();
|
||||
});
|
||||
}
|
||||
});
|
17
packages/webpack5/__tests__/configuration/vue.spec.ts
Normal file
17
packages/webpack5/__tests__/configuration/vue.spec.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import Config from 'webpack-chain';
|
||||
|
||||
import vue from '../../src/configuration/vue';
|
||||
import { init } from '../../src';
|
||||
|
||||
describe('vue configuration', () => {
|
||||
const platforms = ['ios', 'android'];
|
||||
|
||||
for (let platform of platforms) {
|
||||
it(`for ${platform}`, () => {
|
||||
init({
|
||||
[platform]: true,
|
||||
});
|
||||
expect(vue(new Config()).toString()).toMatchSnapshot();
|
||||
});
|
||||
}
|
||||
});
|
86
packages/webpack5/__tests__/helpers/fileReplacements.spec.ts
Normal file
86
packages/webpack5/__tests__/helpers/fileReplacements.spec.ts
Normal file
@ -0,0 +1,86 @@
|
||||
import { getFileReplacementsFromEnv } from '../../src/helpers/fileReplacements';
|
||||
|
||||
describe('getFileReplacementsFromEnv', () => {
|
||||
it('handles no replacements', () => {
|
||||
const res = getFileReplacementsFromEnv({});
|
||||
expect(res).toEqual({});
|
||||
});
|
||||
|
||||
it('ignores invalid env', () => {
|
||||
const res = getFileReplacementsFromEnv({
|
||||
// @ts-ignore
|
||||
replace: {},
|
||||
});
|
||||
expect(res).toEqual({});
|
||||
});
|
||||
|
||||
it('resolves replacements relative to the project root', () => {
|
||||
const res = getFileReplacementsFromEnv({
|
||||
replace: './src/foo.ts:./src/bar.ts',
|
||||
});
|
||||
const entries = Object.entries(res);
|
||||
expect(res).toBeDefined();
|
||||
expect(entries.length).toBe(1);
|
||||
expect(entries[0]).toEqual(['__jest__/src/foo.ts', '__jest__/src/bar.ts']);
|
||||
});
|
||||
|
||||
it('ignores invalid replacements', () => {
|
||||
const res = getFileReplacementsFromEnv({
|
||||
replace: ['one', 'two:', 'three:four'],
|
||||
});
|
||||
const entries = Object.entries(res);
|
||||
expect(res).toBeDefined();
|
||||
expect(entries.length).toBe(1);
|
||||
expect(entries[0]).toEqual(['__jest__/three', '__jest__/four']);
|
||||
});
|
||||
|
||||
it('can parse replacements from a string', () => {
|
||||
const res = getFileReplacementsFromEnv({
|
||||
replace: 'one:two',
|
||||
});
|
||||
const entries = Object.entries(res);
|
||||
expect(res).toBeDefined();
|
||||
expect(entries.length).toBe(1);
|
||||
expect(entries[0]).toEqual(['__jest__/one', '__jest__/two']);
|
||||
});
|
||||
|
||||
it('can parse multiple replacements from a string', () => {
|
||||
const res = getFileReplacementsFromEnv({
|
||||
replace: 'one:two,three:four',
|
||||
});
|
||||
const entries = Object.entries(res);
|
||||
expect(res).toBeDefined();
|
||||
expect(entries.length).toBe(2);
|
||||
expect(entries).toEqual([
|
||||
['__jest__/one', '__jest__/two'],
|
||||
['__jest__/three', '__jest__/four'],
|
||||
]);
|
||||
});
|
||||
|
||||
it('can parse replacements from an array', () => {
|
||||
const res = getFileReplacementsFromEnv({
|
||||
replace: ['one:two', 'three:four'],
|
||||
});
|
||||
const entries = Object.entries(res);
|
||||
expect(res).toBeDefined();
|
||||
expect(entries.length).toBe(2);
|
||||
expect(entries).toEqual([
|
||||
['__jest__/one', '__jest__/two'],
|
||||
['__jest__/three', '__jest__/four'],
|
||||
]);
|
||||
});
|
||||
|
||||
it('can parse multiple replacements from an array', () => {
|
||||
const res = getFileReplacementsFromEnv({
|
||||
replace: ['one:two,three:four', 'five:six'],
|
||||
});
|
||||
const entries = Object.entries(res);
|
||||
expect(res).toBeDefined();
|
||||
expect(entries.length).toBe(3);
|
||||
expect(entries).toEqual([
|
||||
['__jest__/one', '__jest__/two'],
|
||||
['__jest__/three', '__jest__/four'],
|
||||
['__jest__/five', '__jest__/six'],
|
||||
]);
|
||||
});
|
||||
});
|
141
packages/webpack5/__tests__/index.spec.ts
Normal file
141
packages/webpack5/__tests__/index.spec.ts
Normal file
@ -0,0 +1,141 @@
|
||||
describe('@nativescript/webpack', () => {
|
||||
let webpack: typeof import('../src');
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
webpack = require('../src');
|
||||
});
|
||||
|
||||
it('exports the public api', () => {
|
||||
expect(webpack.init).toBeInstanceOf(Function);
|
||||
expect(webpack.useConfig).toBeInstanceOf(Function);
|
||||
expect(webpack.chainWebpack).toBeInstanceOf(Function);
|
||||
expect(webpack.mergeWebpack).toBeInstanceOf(Function);
|
||||
expect(webpack.resolveChainableConfig).toBeInstanceOf(Function);
|
||||
expect(webpack.resolveConfig).toBeInstanceOf(Function);
|
||||
});
|
||||
|
||||
it('applies chain configs', () => {
|
||||
webpack.useConfig(false);
|
||||
|
||||
const chainFn = jest.fn();
|
||||
webpack.chainWebpack(chainFn);
|
||||
|
||||
// chainFn should not be called yet
|
||||
expect(chainFn).not.toHaveBeenCalled();
|
||||
|
||||
// chainFn should only be called when
|
||||
// resolving a chainable config
|
||||
const config = webpack.resolveChainableConfig();
|
||||
|
||||
expect(chainFn).toHaveBeenCalledTimes(1);
|
||||
expect(chainFn).toHaveBeenCalledWith(config, {});
|
||||
});
|
||||
|
||||
it('applies chain configs in the right order', () => {
|
||||
webpack.useConfig(false);
|
||||
let lastCalled = false;
|
||||
|
||||
// this is registered before chainFnNormal
|
||||
// however, should be called after chainFnNormal
|
||||
const chainFnLast = jest.fn((config) => {
|
||||
lastCalled = true;
|
||||
expect(config.normal).toBe(true);
|
||||
});
|
||||
webpack.chainWebpack(chainFnLast, { order: 10 });
|
||||
|
||||
const chainFnNormal = jest.fn((config) => {
|
||||
config.normal = true;
|
||||
|
||||
// chainFnLast should not have been called yet
|
||||
expect(lastCalled).toBe(false);
|
||||
});
|
||||
webpack.chainWebpack(chainFnNormal);
|
||||
|
||||
webpack.resolveChainableConfig();
|
||||
});
|
||||
|
||||
it('prints plugin name that has a chain function that throws an error', () => {
|
||||
webpack.useConfig(false);
|
||||
webpack.setCurrentPlugin('test-plugin');
|
||||
const chainFn = jest.fn(() => {
|
||||
throw new Error('something wrong');
|
||||
});
|
||||
webpack.chainWebpack(chainFn);
|
||||
|
||||
// should not throw
|
||||
expect(() => webpack.resolveChainableConfig()).not.toThrow();
|
||||
|
||||
expect(
|
||||
'Unable to apply chain function from: test-plugin'
|
||||
).toHaveBeenWarned();
|
||||
});
|
||||
|
||||
it('applies merge configs', () => {
|
||||
const dummyEnv = { foo: true };
|
||||
webpack.init(dummyEnv);
|
||||
webpack.useConfig(false);
|
||||
|
||||
const mergeFn = jest.fn();
|
||||
webpack.mergeWebpack(mergeFn);
|
||||
|
||||
// mergeFn should not be called yet
|
||||
expect(mergeFn).not.toHaveBeenCalled();
|
||||
|
||||
const config = webpack.resolveChainableConfig();
|
||||
|
||||
// mergeFn should not be called yet
|
||||
expect(mergeFn).not.toHaveBeenCalled();
|
||||
|
||||
// mergeFn should only be called when
|
||||
// resolving the final config
|
||||
webpack.resolveConfig();
|
||||
|
||||
expect(mergeFn).toHaveBeenCalledTimes(1);
|
||||
expect(mergeFn).toHaveBeenCalledWith(config.toConfig(), dummyEnv);
|
||||
});
|
||||
|
||||
it('merges mutate config', () => {
|
||||
const dummyEnv = { foo: true };
|
||||
webpack.init(dummyEnv);
|
||||
webpack.useConfig(false);
|
||||
|
||||
webpack.mergeWebpack((config) => {
|
||||
(config as any).mutated = true;
|
||||
});
|
||||
|
||||
expect(webpack.resolveConfig()).toMatchObject({
|
||||
mutated: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('merges returned config', () => {
|
||||
const dummyEnv = { foo: true };
|
||||
webpack.init(dummyEnv);
|
||||
webpack.useConfig(false);
|
||||
|
||||
webpack.mergeWebpack(() => {
|
||||
return {
|
||||
returned: true,
|
||||
};
|
||||
});
|
||||
|
||||
expect(webpack.resolveConfig()).toMatchObject({
|
||||
returned: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('merges objects', () => {
|
||||
const dummyEnv = { foo: true };
|
||||
webpack.init(dummyEnv);
|
||||
webpack.useConfig(false);
|
||||
|
||||
webpack.mergeWebpack({
|
||||
object: true,
|
||||
} as any);
|
||||
|
||||
expect(webpack.resolveConfig()).toMatchObject({
|
||||
object: true,
|
||||
});
|
||||
});
|
||||
});
|
426
packages/webpack5/__tests__/loaders/xml-namespace-loader.spec.ts
Normal file
426
packages/webpack5/__tests__/loaders/xml-namespace-loader.spec.ts
Normal file
@ -0,0 +1,426 @@
|
||||
import dedent from 'ts-dedent';
|
||||
|
||||
import xmlNsLoader from '../../src/loaders/xml-namespace-loader';
|
||||
|
||||
const CODE_FILE = dedent`
|
||||
<Page xmlns="http://www.nativescript.org/tns.xsd">
|
||||
<StackLayout>
|
||||
<GridLayout xmlns:chart="nativescript-ui-chart">
|
||||
<chart:RadCartesianChart></chart:RadCartesianChart>
|
||||
</GridLayout>
|
||||
<GridLayout xmlns:chart="nativescript-ui-chart">
|
||||
<chart:RadCartesianChart></chart:RadCartesianChart>
|
||||
</GridLayout>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
`;
|
||||
|
||||
interface TestSetup {
|
||||
resolveMap: { [path: string]: string };
|
||||
expectedDeps: string[];
|
||||
expectedRegs: { name: string; path: string }[];
|
||||
ignore?: RegExp;
|
||||
assureNoDeps?: boolean;
|
||||
expectError?: boolean;
|
||||
expectWarnings?: number;
|
||||
}
|
||||
|
||||
function getContext(
|
||||
done,
|
||||
{
|
||||
resolveMap,
|
||||
expectedDeps,
|
||||
expectedRegs,
|
||||
assureNoDeps,
|
||||
ignore,
|
||||
expectError,
|
||||
expectWarnings,
|
||||
}: TestSetup
|
||||
) {
|
||||
const actualDeps: string[] = [];
|
||||
const actualWarnings: Error[] = [];
|
||||
let callbackCalled = false;
|
||||
|
||||
return {
|
||||
rootContext: 'app',
|
||||
context: 'app/component',
|
||||
async: () => (error, source: string) => {
|
||||
if (callbackCalled) {
|
||||
done.fail('Callback called more than once!');
|
||||
}
|
||||
callbackCalled = true;
|
||||
|
||||
expectedDeps.forEach((expectedDep) => {
|
||||
expect(actualDeps).toContain(expectedDep);
|
||||
});
|
||||
|
||||
expectedRegs.forEach(({ name, path }) => {
|
||||
expect(source).toContain(dedent`
|
||||
global.registerModule(
|
||||
'${name}',
|
||||
() => require("${path}")
|
||||
)
|
||||
`);
|
||||
});
|
||||
|
||||
if (assureNoDeps) {
|
||||
expect(actualDeps.length).toBe(0);
|
||||
expect(source).not.toContain('global.registerModule');
|
||||
}
|
||||
|
||||
if (expectWarnings) {
|
||||
expect(actualWarnings.length).toEqual(expectWarnings);
|
||||
}
|
||||
|
||||
if (error && !expectError) {
|
||||
done.fail(error);
|
||||
} else if (!error && expectError) {
|
||||
done.fail('Error expected here');
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
},
|
||||
resolve: (
|
||||
context: string,
|
||||
request: string,
|
||||
callback: (err: Error, result: string) => void
|
||||
) => {
|
||||
request = request.replace(/\\/g, '/');
|
||||
if (resolveMap[request]) {
|
||||
callback(undefined, resolveMap[request]);
|
||||
} else {
|
||||
callback(new Error(`Module ${request} not found`), undefined);
|
||||
}
|
||||
},
|
||||
addDependency: (dep: string) => {
|
||||
actualDeps.push(dep);
|
||||
},
|
||||
emitWarning: (err: Error) => {
|
||||
actualWarnings.push(err);
|
||||
},
|
||||
emitError: (err: Error) => {
|
||||
//actualWarnings.push(err);
|
||||
},
|
||||
query: { ignore },
|
||||
};
|
||||
}
|
||||
|
||||
describe('xml-namespace-loader', () => {
|
||||
it('with namespace pointing to files', (done) => {
|
||||
const resolveMap = {
|
||||
'app/nativescript-ui-chart': 'app/nativescript-ui-chart.js',
|
||||
'app/nativescript-ui-chart.xml': 'app/nativescript-ui-chart.xml',
|
||||
'app/nativescript-ui-chart.css': 'app/nativescript-ui-chart.css',
|
||||
};
|
||||
|
||||
const expectedDeps = [
|
||||
'app/nativescript-ui-chart.js',
|
||||
'app/nativescript-ui-chart.xml',
|
||||
'app/nativescript-ui-chart.css',
|
||||
];
|
||||
|
||||
const expectedRegs = [
|
||||
{ name: 'nativescript-ui-chart', path: 'app/nativescript-ui-chart.js' },
|
||||
{
|
||||
name: 'nativescript-ui-chart/RadCartesianChart',
|
||||
path: 'app/nativescript-ui-chart.js',
|
||||
},
|
||||
{
|
||||
name: 'nativescript-ui-chart/RadCartesianChart.xml',
|
||||
path: 'app/nativescript-ui-chart.xml',
|
||||
},
|
||||
{
|
||||
name: 'nativescript-ui-chart/RadCartesianChart.css',
|
||||
path: 'app/nativescript-ui-chart.css',
|
||||
},
|
||||
];
|
||||
|
||||
const loaderContext = getContext(done, {
|
||||
resolveMap,
|
||||
expectedDeps,
|
||||
expectedRegs,
|
||||
});
|
||||
|
||||
xmlNsLoader.call(loaderContext, CODE_FILE);
|
||||
});
|
||||
|
||||
it('with namespace/elementName pointing to files (with package.json)', (done) => {
|
||||
const resolveMap = {
|
||||
'app/nativescript-ui-chart':
|
||||
'app/nativescript-ui-chart/RadCartesianChart.js', //simulate package.json
|
||||
'app/nativescript-ui-chart/RadCartesianChart':
|
||||
'app/nativescript-ui-chart/RadCartesianChart.js',
|
||||
'app/nativescript-ui-chart/RadCartesianChart.xml':
|
||||
'app/nativescript-ui-chart/RadCartesianChart.xml',
|
||||
'app/nativescript-ui-chart/RadCartesianChart.css':
|
||||
'app/nativescript-ui-chart/RadCartesianChart.css',
|
||||
};
|
||||
|
||||
const expectedDeps = [
|
||||
'app/nativescript-ui-chart/RadCartesianChart.js',
|
||||
'app/nativescript-ui-chart/RadCartesianChart.xml',
|
||||
'app/nativescript-ui-chart/RadCartesianChart.css',
|
||||
];
|
||||
|
||||
const expectedRegs = [
|
||||
{
|
||||
name: 'nativescript-ui-chart',
|
||||
path: 'app/nativescript-ui-chart/RadCartesianChart.js',
|
||||
},
|
||||
{
|
||||
name: 'nativescript-ui-chart/RadCartesianChart',
|
||||
path: 'app/nativescript-ui-chart/RadCartesianChart.js',
|
||||
},
|
||||
{
|
||||
name: 'nativescript-ui-chart/RadCartesianChart.xml',
|
||||
path: 'app/nativescript-ui-chart/RadCartesianChart.xml',
|
||||
},
|
||||
{
|
||||
name: 'nativescript-ui-chart/RadCartesianChart.css',
|
||||
path: 'app/nativescript-ui-chart/RadCartesianChart.css',
|
||||
},
|
||||
];
|
||||
|
||||
const loaderContext = getContext(done, {
|
||||
resolveMap,
|
||||
expectedDeps,
|
||||
expectedRegs,
|
||||
});
|
||||
xmlNsLoader.call(loaderContext, CODE_FILE);
|
||||
});
|
||||
|
||||
it('with namespace/elementName pointing to files', (done) => {
|
||||
const resolveMap = {
|
||||
'app/nativescript-ui-chart/RadCartesianChart':
|
||||
'app/nativescript-ui-chart/RadCartesianChart.js',
|
||||
'app/nativescript-ui-chart/RadCartesianChart.xml':
|
||||
'app/nativescript-ui-chart/RadCartesianChart.xml',
|
||||
'app/nativescript-ui-chart/RadCartesianChart.css':
|
||||
'app/nativescript-ui-chart/RadCartesianChart.css',
|
||||
};
|
||||
|
||||
const expectedDeps = [
|
||||
'app/nativescript-ui-chart/RadCartesianChart.js',
|
||||
'app/nativescript-ui-chart/RadCartesianChart.xml',
|
||||
'app/nativescript-ui-chart/RadCartesianChart.css',
|
||||
];
|
||||
|
||||
const expectedRegs = [
|
||||
{
|
||||
name: 'nativescript-ui-chart',
|
||||
path: 'app/nativescript-ui-chart/RadCartesianChart.js',
|
||||
},
|
||||
{
|
||||
name: 'nativescript-ui-chart/RadCartesianChart',
|
||||
path: 'app/nativescript-ui-chart/RadCartesianChart.js',
|
||||
},
|
||||
{
|
||||
name: 'nativescript-ui-chart/RadCartesianChart.xml',
|
||||
path: 'app/nativescript-ui-chart/RadCartesianChart.xml',
|
||||
},
|
||||
{
|
||||
name: 'nativescript-ui-chart/RadCartesianChart.css',
|
||||
path: 'app/nativescript-ui-chart/RadCartesianChart.css',
|
||||
},
|
||||
];
|
||||
|
||||
const loaderContext = getContext(done, {
|
||||
resolveMap,
|
||||
expectedDeps,
|
||||
expectedRegs,
|
||||
});
|
||||
xmlNsLoader.call(loaderContext, CODE_FILE);
|
||||
});
|
||||
|
||||
it('with namespace/elementName pointing to files - only XML and CSS', (done) => {
|
||||
const resolveMap = {
|
||||
'app/nativescript-ui-chart/RadCartesianChart.xml':
|
||||
'app/nativescript-ui-chart/RadCartesianChart.xml',
|
||||
'app/nativescript-ui-chart/RadCartesianChart.css':
|
||||
'app/nativescript-ui-chart/RadCartesianChart.css',
|
||||
};
|
||||
|
||||
const expectedDeps = [
|
||||
'app/nativescript-ui-chart/RadCartesianChart.xml',
|
||||
'app/nativescript-ui-chart/RadCartesianChart.css',
|
||||
];
|
||||
|
||||
const expectedRegs = [
|
||||
{
|
||||
name: 'nativescript-ui-chart/RadCartesianChart.xml',
|
||||
path: 'app/nativescript-ui-chart/RadCartesianChart.xml',
|
||||
},
|
||||
{
|
||||
name: 'nativescript-ui-chart/RadCartesianChart.css',
|
||||
path: 'app/nativescript-ui-chart/RadCartesianChart.css',
|
||||
},
|
||||
];
|
||||
|
||||
const loaderContext = getContext(done, {
|
||||
resolveMap,
|
||||
expectedDeps,
|
||||
expectedRegs,
|
||||
});
|
||||
xmlNsLoader.call(loaderContext, CODE_FILE);
|
||||
});
|
||||
|
||||
it('with plugin path', (done) => {
|
||||
const resolveMap = {
|
||||
'nativescript-ui-chart': 'node_modules/nativescript-ui-chart/ui-chart.js',
|
||||
};
|
||||
|
||||
const expectedDeps = [];
|
||||
|
||||
const expectedRegs = [
|
||||
{ name: 'nativescript-ui-chart', path: 'nativescript-ui-chart' },
|
||||
{
|
||||
name: 'nativescript-ui-chart/RadCartesianChart',
|
||||
path: 'nativescript-ui-chart',
|
||||
},
|
||||
];
|
||||
|
||||
const loaderContext = getContext(done, {
|
||||
resolveMap,
|
||||
expectedDeps,
|
||||
expectedRegs,
|
||||
});
|
||||
xmlNsLoader.call(loaderContext, CODE_FILE);
|
||||
});
|
||||
|
||||
it('with ignored namespace should not add deps or register calls', (done) => {
|
||||
const resolveMap = {
|
||||
'app/nativescript-ui-chart': 'app/nativescript-ui-chart.js',
|
||||
'app/nativescript-ui-chart.xml': 'app/nativescript-ui-chart.xml',
|
||||
'app/nativescript-ui-chart.css': 'app/nativescript-ui-chart.css',
|
||||
};
|
||||
const expectedDeps = [];
|
||||
const expectedRegs = [];
|
||||
|
||||
const loaderContext = getContext(done, {
|
||||
resolveMap,
|
||||
expectedDeps,
|
||||
expectedRegs,
|
||||
ignore: /nativescript-ui-chart/,
|
||||
assureNoDeps: true,
|
||||
});
|
||||
|
||||
xmlNsLoader.call(loaderContext, CODE_FILE);
|
||||
});
|
||||
|
||||
it('with XML declaration and Doctype does not fail', (done) => {
|
||||
const resolveMap = {};
|
||||
const expectedDeps = [];
|
||||
const expectedRegs = [];
|
||||
|
||||
const testXml = dedent`
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<!-- comment.xml -->
|
||||
<Page xmlns="http://www.nativescript.org/tns.xsd"></Page>
|
||||
`;
|
||||
|
||||
const loaderContext = getContext(done, {
|
||||
resolveMap,
|
||||
expectedDeps,
|
||||
expectedRegs,
|
||||
assureNoDeps: true,
|
||||
});
|
||||
|
||||
xmlNsLoader.call(loaderContext, testXml);
|
||||
});
|
||||
|
||||
it('with invalid XML fails', (done) => {
|
||||
const resolveMap = {};
|
||||
const expectedDeps = [];
|
||||
const expectedRegs = [];
|
||||
|
||||
const testXml = `<Page xmlns="http://www.nativescript.org/tns.xsd"></PageOpsWrongTagHere>`;
|
||||
|
||||
const loaderContext = getContext(done, {
|
||||
resolveMap,
|
||||
expectedDeps,
|
||||
expectedRegs,
|
||||
expectError: true,
|
||||
});
|
||||
|
||||
xmlNsLoader.call(loaderContext, testXml);
|
||||
});
|
||||
|
||||
it("doesn't throw with ios and android platform namespaces", (done) => {
|
||||
const resolveMap = {};
|
||||
const expectedDeps = [];
|
||||
const expectedRegs = [];
|
||||
|
||||
const testXml = dedent`
|
||||
<Page xmlns="http://www.nativescript.org/tns.xsd">
|
||||
<ios:GridLayout />
|
||||
<ios:GridLayout></ios:GridLayout>
|
||||
<android:GridLayout />
|
||||
<android:GridLayout></android:GridLayout>
|
||||
</Page>
|
||||
`;
|
||||
|
||||
const loaderContext = getContext(done, {
|
||||
resolveMap,
|
||||
expectedDeps,
|
||||
expectedRegs,
|
||||
assureNoDeps: true,
|
||||
});
|
||||
|
||||
xmlNsLoader.call(loaderContext, testXml);
|
||||
});
|
||||
|
||||
it('throws with unbound namespace namespaces', (done) => {
|
||||
const resolveMap = {};
|
||||
const expectedDeps = [];
|
||||
const expectedRegs = [];
|
||||
|
||||
const testXml = `
|
||||
<Page xmlns="http://www.nativescript.org/tns.xsd">
|
||||
<custom1:CustomComponent />
|
||||
<custom2:CustomComponent />
|
||||
</Page>`;
|
||||
|
||||
const loaderContext = getContext(done, {
|
||||
resolveMap,
|
||||
expectedDeps,
|
||||
expectedRegs,
|
||||
expectError: true,
|
||||
});
|
||||
|
||||
xmlNsLoader.call(loaderContext, testXml);
|
||||
});
|
||||
|
||||
it("with '&&', '||', '<=' and '>=' in binding expression, emits warnings, but does not fail", (done) => {
|
||||
const resolveMap = {
|
||||
'nativescript-ui-chart': 'node_modules/nativescript-ui-chart/ui-chart.js',
|
||||
};
|
||||
|
||||
const expectedDeps = [];
|
||||
|
||||
const expectedRegs = [
|
||||
{ name: 'nativescript-ui-chart', path: 'nativescript-ui-chart' },
|
||||
{
|
||||
name: 'nativescript-ui-chart/RadCartesianChart',
|
||||
path: 'nativescript-ui-chart',
|
||||
},
|
||||
];
|
||||
|
||||
const testXml = `
|
||||
<Page xmlns="http://www.nativescript.org/tns.xsd">
|
||||
<StackLayout xmlns:chart="nativescript-ui-chart">
|
||||
<TextField text="{{ var1 && var2 || var1 >= var2 || var2 <= var1 }}" />
|
||||
<chart:RadCartesianChart></chart:RadCartesianChart>
|
||||
</StackLayout>
|
||||
</Page>`;
|
||||
|
||||
const loaderContext = getContext(done, {
|
||||
resolveMap,
|
||||
expectedDeps,
|
||||
expectedRegs,
|
||||
expectWarnings: 1,
|
||||
});
|
||||
|
||||
xmlNsLoader.call(loaderContext, testXml);
|
||||
});
|
||||
});
|
17
packages/webpack5/jest.config.js
Normal file
17
packages/webpack5/jest.config.js
Normal file
@ -0,0 +1,17 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
moduleNameMapper: {
|
||||
'^@nativescript/webpack$': '<rootDir>/src'
|
||||
},
|
||||
setupFiles: [
|
||||
'<rootDir>/scripts/jest.setup.ts'
|
||||
],
|
||||
setupFilesAfterEnv: [
|
||||
'<rootDir>/scripts/jest.mockWarn.ts',
|
||||
'<rootDir>/scripts/jest.copyRules.ts'
|
||||
],
|
||||
globals: {
|
||||
__TEST__: true,
|
||||
}
|
||||
};
|
77
packages/webpack5/package.json
Normal file
77
packages/webpack5/package.json
Normal file
@ -0,0 +1,77 @@
|
||||
{
|
||||
"name": "@nativescript/webpack",
|
||||
"version": "5.0.0-dev",
|
||||
"private": true,
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"bin": {
|
||||
"nativescript-webpack": "dist/bin/index.js"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"build": "tsc --project tsconfig.build.json",
|
||||
"test": "jest",
|
||||
"copy-stubs": "mkdirp dist/stubs && cp -R src/stubs/* dist/stubs",
|
||||
"prepack": "npm test && npm run build && npm run copy-stubs && chmod +x dist/bin/index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "7.13.14",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "0.4.3",
|
||||
"babel-loader": "8.2.2",
|
||||
"chalk": "4.1.0",
|
||||
"cli-highlight": "2.1.11",
|
||||
"commander": "7.2.0",
|
||||
"copy-webpack-plugin": "8.1.0",
|
||||
"css": "3.0.0",
|
||||
"css-loader": "5.2.0",
|
||||
"dotenv-webpack": "7.0.2",
|
||||
"fork-ts-checker-webpack-plugin": "6.2.0",
|
||||
"loader-utils": "2.0.0",
|
||||
"lodash.get": "4.4.2",
|
||||
"micromatch": "4.0.2",
|
||||
"postcss": "8.2.8",
|
||||
"postcss-import": "14.0.0",
|
||||
"postcss-loader": "5.2.0",
|
||||
"raw-loader": "4.0.2",
|
||||
"react-refresh": "0.10.0",
|
||||
"sass": "1.32.8",
|
||||
"sass-loader": "11.0.1",
|
||||
"sax": "1.2.4",
|
||||
"source-map": "0.7.3",
|
||||
"terser-webpack-plugin": "5.1.1",
|
||||
"ts-dedent": "2.1.0",
|
||||
"ts-loader": "8.1.0",
|
||||
"vue-loader": "15.9.6",
|
||||
"webpack": "5.28.0",
|
||||
"webpack-bundle-analyzer": "4.4.0",
|
||||
"webpack-chain": "6.5.1",
|
||||
"webpack-cli": "4.6.0",
|
||||
"webpack-merge": "5.7.3",
|
||||
"webpack-virtual-modules": "0.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash.get": "4.4.6",
|
||||
"@types/sax": "1.2.1",
|
||||
"@types/css": "0.0.31",
|
||||
"@types/jest": "26.0.22",
|
||||
"@types/loader-utils": "2.0.2",
|
||||
"@types/micromatch": "4.0.1",
|
||||
"@types/terser-webpack-plugin": "5.0.3",
|
||||
"@types/webpack-virtual-modules": "0.1.1",
|
||||
"jest": "26.6.3",
|
||||
"jest-matcher-utils": "26.6.2",
|
||||
"nativescript-vue-template-compiler": "2.8.4",
|
||||
"ts-jest": "26.5.4",
|
||||
"typescript": "4.2.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"nativescript-vue-template-compiler": "^2.8.1"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"nativescript-vue-template-compiler": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
7
packages/webpack5/scripts/jest.copyRules.ts
Normal file
7
packages/webpack5/scripts/jest.copyRules.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { copyRules, additionalCopyRules } from '../src/helpers/copyRules';
|
||||
|
||||
afterEach(() => {
|
||||
// Clear copy rules
|
||||
copyRules.clear();
|
||||
additionalCopyRules.length = 0
|
||||
});
|
8
packages/webpack5/scripts/jest.globals.d.ts
vendored
Normal file
8
packages/webpack5/scripts/jest.globals.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
// define test-specific globals here
|
||||
|
||||
declare namespace jest {
|
||||
interface Matchers<R, T> {
|
||||
toHaveBeenWarned(): R;
|
||||
toHaveBeenPrinted(): R;
|
||||
}
|
||||
}
|
64
packages/webpack5/scripts/jest.mockWarn.ts
Normal file
64
packages/webpack5/scripts/jest.mockWarn.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { printExpected, printReceived } from 'jest-matcher-utils';
|
||||
import dedent from 'ts-dedent';
|
||||
|
||||
expect.extend({
|
||||
toHaveBeenWarned(received: string) {
|
||||
asserted.add(received);
|
||||
const passed = warnSpy.mock.calls
|
||||
.map((args) => args[1])
|
||||
.some((arg) => arg.indexOf(received) > -1);
|
||||
if (passed) {
|
||||
return {
|
||||
pass: true,
|
||||
message() {
|
||||
return `expected ${printReceived(received)} not to have been warned`;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const warnings = warnSpy.mock.calls.map((args) => args[1]).join('\n\n');
|
||||
return {
|
||||
pass: false,
|
||||
message() {
|
||||
return dedent`
|
||||
expected ${printExpected(received)} to have been warned.
|
||||
|
||||
Actual warnings:
|
||||
|
||||
${warnings}
|
||||
`;
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
let warnSpy: any;
|
||||
let asserted = new Set([]);
|
||||
beforeEach(() => {
|
||||
asserted.clear();
|
||||
|
||||
warnSpy = jest.spyOn(console, 'warn');
|
||||
|
||||
warnSpy.mockImplementation(() => {});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
const assertedArray = Array.from(asserted);
|
||||
const nonAssertedWarns = warnSpy.mock.calls
|
||||
.map((args) => args[1])
|
||||
.filter((received) => {
|
||||
return !assertedArray.some((assertedMessage) => {
|
||||
return received.indexOf(assertedMessage) > -1;
|
||||
});
|
||||
});
|
||||
|
||||
warnSpy.mockRestore();
|
||||
|
||||
if (nonAssertedWarns.length) {
|
||||
throw new Error(dedent`
|
||||
Test case printed unexpected warnings:
|
||||
|
||||
${printReceived(nonAssertedWarns.join('\n\n'))}
|
||||
`);
|
||||
}
|
||||
});
|
100
packages/webpack5/scripts/jest.setup.ts
Normal file
100
packages/webpack5/scripts/jest.setup.ts
Normal file
@ -0,0 +1,100 @@
|
||||
// we are mocking the cwd for the tests, since webpack needs absolute paths
|
||||
// and we don't want them in tests
|
||||
process.cwd = () => '__jest__';
|
||||
|
||||
jest.mock('cosmiconfig', () => ({
|
||||
cosmiconfigSync(moduleName) {
|
||||
return {
|
||||
search() {
|
||||
// no-op in tests
|
||||
return null;
|
||||
},
|
||||
};
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('../src/helpers/config.ts', () => ({
|
||||
getValue(key, defaultValue) {
|
||||
return defaultValue;
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('os', () => {
|
||||
const os = jest.requireActual('os');
|
||||
|
||||
return {
|
||||
...os,
|
||||
networkInterfaces() {
|
||||
return {
|
||||
in0: [
|
||||
{
|
||||
address: '127.0.0.1',
|
||||
family: 'IPv4',
|
||||
},
|
||||
{
|
||||
address: 'in0-ipv6-should-not-use',
|
||||
family: 'IPv6',
|
||||
},
|
||||
],
|
||||
in1: [
|
||||
{
|
||||
address: '192.168.0.10',
|
||||
family: 'IPv4',
|
||||
},
|
||||
{
|
||||
address: 'in1-ipv6-should-not-use',
|
||||
family: 'IPv6',
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('path', () => {
|
||||
const path = jest.requireActual('path');
|
||||
return {
|
||||
...path,
|
||||
resolve(...args) {
|
||||
if (args[0] === '__jest__') {
|
||||
return path.join(...args.filter(Boolean));
|
||||
}
|
||||
|
||||
const resolved = path.resolve(...args);
|
||||
if (resolved.includes('__jest__')) {
|
||||
const li = resolved.lastIndexOf('__jest__');
|
||||
return resolved.substr(li);
|
||||
}
|
||||
|
||||
// handle resolutions with __dirname
|
||||
// used in base config's resolveLoader
|
||||
const root = path.resolve(__dirname, '..');
|
||||
if (resolved.startsWith(root)) {
|
||||
const newPath = resolved.replace(root, '__jest__');
|
||||
|
||||
if (newPath.startsWith('__jest__/src')) {
|
||||
return newPath.replace(
|
||||
'__jest__/src',
|
||||
'__jest__/node_modules/@nativescript/webpack/dist'
|
||||
);
|
||||
}
|
||||
|
||||
return newPath;
|
||||
}
|
||||
|
||||
return resolved;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
// a virtual mock for package.json
|
||||
jest.mock(
|
||||
'__jest__/package.json',
|
||||
() => ({
|
||||
main: 'src/app.js',
|
||||
devDependencies: {
|
||||
typescript: '*',
|
||||
},
|
||||
}),
|
||||
{ virtual: true }
|
||||
);
|
56
packages/webpack5/src/bin/devServer.ts
Normal file
56
packages/webpack5/src/bin/devServer.ts
Normal file
@ -0,0 +1,56 @@
|
||||
// import { createServer } from 'http'
|
||||
//
|
||||
// export interface IHMRStatusData {
|
||||
// seq: number
|
||||
// uuid: string,
|
||||
// hash: string
|
||||
// status: string
|
||||
// }
|
||||
//
|
||||
// export function run() {
|
||||
// createServer((req, res) => {
|
||||
// if (req.url === '/ping') {
|
||||
// console.log('PING -> PONG!')
|
||||
// return res.end("Pong.");
|
||||
// }
|
||||
//
|
||||
// if (req.method !== 'POST') {
|
||||
// res.statusCode = 400;
|
||||
// return res.end("Unsupported method.");
|
||||
// }
|
||||
//
|
||||
// let data = "";
|
||||
// req.on("data", chunk => {
|
||||
// data += chunk;
|
||||
// });
|
||||
//
|
||||
// req.on("end", () => {
|
||||
// try {
|
||||
// const signal = JSON.parse(data) as IHMRStatusData;
|
||||
// // if (!statuses[signal.hash] || statuses[signal.hash].seq < signal.seq) {
|
||||
// // statuses[signal.hash] = signal
|
||||
// // }
|
||||
// if (process.send) {
|
||||
// process.send({
|
||||
// type: 'hmr-status',
|
||||
// version: 1,
|
||||
// hash: signal.hash,
|
||||
// data: signal
|
||||
// }, (error) => {
|
||||
// if (error) {
|
||||
// console.error(`Process Send Error: `, error);
|
||||
// }
|
||||
//
|
||||
// return null;
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// res.end('ok.');
|
||||
// } catch (e) {
|
||||
// res.statusCode = 400;
|
||||
// res.end("Invalid JSON.");
|
||||
// }
|
||||
// });
|
||||
// }).listen(8238)
|
||||
// }
|
||||
//
|
122
packages/webpack5/src/bin/index.ts
Normal file
122
packages/webpack5/src/bin/index.ts
Normal file
@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { redBright, green, greenBright } from 'chalk';
|
||||
import { program } from 'commander';
|
||||
import dedent from 'ts-dedent';
|
||||
import webpack from 'webpack';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
import { parseEnvFlags } from '../cli/parseEnvFlags';
|
||||
|
||||
const defaultConfig = path.resolve(
|
||||
__dirname,
|
||||
'../stubs/default.config.stub.js'
|
||||
);
|
||||
const tag = `[${green('@nativescript/webpack')}]`;
|
||||
|
||||
function error(message: string) {
|
||||
console.error(`${tag} ${redBright(dedent(message))}`);
|
||||
}
|
||||
|
||||
function info(message: string) {
|
||||
console.info(`${tag} ${greenBright(dedent(message))}`);
|
||||
}
|
||||
|
||||
program.enablePositionalOptions();
|
||||
|
||||
program
|
||||
.command('init')
|
||||
.description('Initialize a new webpack.config.js in the current directory.')
|
||||
.action(() => {
|
||||
const targetPath = path.resolve(process.cwd(), 'webpack.config.js');
|
||||
|
||||
if (fs.existsSync(targetPath)) {
|
||||
return error(`File Already Exists: ${targetPath}`);
|
||||
}
|
||||
|
||||
fs.copyFileSync(defaultConfig, targetPath);
|
||||
|
||||
info('Initialized config.');
|
||||
});
|
||||
|
||||
program
|
||||
.command('build')
|
||||
.description('Build...')
|
||||
.option('--env [name]', 'environment name')
|
||||
.option('--config [path]', 'config path')
|
||||
.option('--watch', 'watch for changes')
|
||||
.allowUnknownOption()
|
||||
.action((options, command) => {
|
||||
const env = parseEnvFlags(command.args);
|
||||
// add --env <val> into the env object
|
||||
// for example if we use --env prod
|
||||
// we'd have env.env = 'prod'
|
||||
if (options.env) {
|
||||
env['env'] = options.env;
|
||||
}
|
||||
|
||||
const configPath = (() => {
|
||||
if (options.config) {
|
||||
return path.resolve(options.config);
|
||||
}
|
||||
|
||||
return path.resolve(process.cwd(), 'webpack.config.js');
|
||||
})();
|
||||
|
||||
// todo: validate config exists
|
||||
// todo: guard against invalid config
|
||||
let configuration: webpack.Configuration;
|
||||
try {
|
||||
configuration = require(configPath)(env);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
if (!configuration) {
|
||||
console.log('No configuration!');
|
||||
return;
|
||||
}
|
||||
|
||||
const compiler = webpack(configuration);
|
||||
|
||||
const webpackCompilationCallback = (
|
||||
err: webpack.WebpackError,
|
||||
stats: webpack.Stats
|
||||
) => {
|
||||
if (err) {
|
||||
// Do not keep cache anymore
|
||||
compiler.purgeInputFileSystem();
|
||||
|
||||
console.error(err.stack || err);
|
||||
if (err.details) {
|
||||
console.error(err.details);
|
||||
}
|
||||
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (stats) {
|
||||
console.log(
|
||||
stats.toString({
|
||||
chunks: false,
|
||||
colors: true,
|
||||
errorDetails: env.verbose,
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
if (options.watch) {
|
||||
console.log('webpack is watching the files...');
|
||||
compiler.watch(
|
||||
configuration.watchOptions ?? {},
|
||||
webpackCompilationCallback
|
||||
);
|
||||
} else {
|
||||
compiler.run(webpackCompilationCallback);
|
||||
}
|
||||
});
|
||||
|
||||
program.parse(process.argv);
|
39
packages/webpack5/src/cli/parseEnvFlags.ts
Normal file
39
packages/webpack5/src/cli/parseEnvFlags.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import type { IWebpackEnv } from '@nativescript/webpack';
|
||||
|
||||
const ENV_FLAG_RE = /--env\.(\w+)(?:=(.+))?/;
|
||||
|
||||
export function parseEnvFlags(flags: string[]): IWebpackEnv {
|
||||
const envFlags = flags.filter((flag) => flag.includes('--env.'));
|
||||
|
||||
const env = {};
|
||||
|
||||
envFlags.map((flag) => {
|
||||
let [_, name, v] = ENV_FLAG_RE.exec(flag);
|
||||
let value: any = v;
|
||||
|
||||
// convert --env.foo to --env.foo=true
|
||||
if (value === undefined) {
|
||||
value = true;
|
||||
}
|
||||
|
||||
// convert true/false to boolean
|
||||
if (value === 'true' || value === 'false') {
|
||||
value = value === 'true';
|
||||
}
|
||||
|
||||
// convert numbers
|
||||
if (!isNaN(value) && !isNaN(parseFloat(value))) {
|
||||
value = +value;
|
||||
}
|
||||
|
||||
// duplicate key/name - convert to array
|
||||
if (name in env && value) {
|
||||
const orig = Array.isArray(env[name]) ? env[name] : [env[name]];
|
||||
env[name] = [...orig, value];
|
||||
} else {
|
||||
env[name] = value;
|
||||
}
|
||||
});
|
||||
|
||||
return env;
|
||||
}
|
116
packages/webpack5/src/configuration/angular.ts
Normal file
116
packages/webpack5/src/configuration/angular.ts
Normal file
@ -0,0 +1,116 @@
|
||||
import Config from 'webpack-chain';
|
||||
import { existsSync } from 'fs';
|
||||
|
||||
import { getProjectFilePath } from '../helpers/project';
|
||||
import { env as _env, IWebpackEnv } from '../index';
|
||||
import { getEntryPath } from '../helpers/platform';
|
||||
import base from './base';
|
||||
|
||||
export default function (config: Config, env: IWebpackEnv = _env): Config {
|
||||
base(config, env);
|
||||
|
||||
const tsConfigPath = [
|
||||
getProjectFilePath('tsconfig.app.json'),
|
||||
getProjectFilePath('tsconfig.json'),
|
||||
].find((path) => existsSync(path));
|
||||
|
||||
// remove default ts rule
|
||||
config.module.rules.delete('ts');
|
||||
|
||||
// remove fork ts checked as not needed
|
||||
config.plugins.delete('ForkTsCheckerWebpackPlugin');
|
||||
|
||||
// explicitly define mainFields to make sure ngcc compiles as es2015 (module field)
|
||||
// instead of umd (main field).
|
||||
config.resolve.mainFields.add('module').add('main');
|
||||
|
||||
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');
|
||||
|
||||
// exclude component css files from the normal css rule
|
||||
config.module.rule('css').exclude.add(/\.component\.css$/);
|
||||
|
||||
// and instead use raw-loader, since that's what angular expects
|
||||
config.module
|
||||
.rule('css|component')
|
||||
.test(/\.component\.css$/)
|
||||
.use('raw-loader')
|
||||
.loader('raw-loader');
|
||||
|
||||
// get base postCSS options
|
||||
const postCSSOptions = config.module
|
||||
.rule('scss')
|
||||
.uses.get('postcss-loader')
|
||||
.get('options');
|
||||
|
||||
// exclude component css files from the normal css rule
|
||||
config.module.rule('scss').exclude.add(/\.component\.scss$/);
|
||||
|
||||
// and instead use raw-loader, since that's what angular expects
|
||||
config.module
|
||||
.rule('scss|component')
|
||||
.test(/\.component\.scss$/)
|
||||
.use('raw-loader')
|
||||
.loader('raw-loader')
|
||||
.end()
|
||||
.use('postcss-loader')
|
||||
.loader('postcss-loader')
|
||||
.options(postCSSOptions)
|
||||
.end()
|
||||
.use('sass-loader')
|
||||
.loader('sass-loader');
|
||||
|
||||
config.plugin('AngularCompilerPlugin').use(getAngularCompilerPlugin(), [
|
||||
{
|
||||
tsConfigPath,
|
||||
mainPath: getEntryPath(),
|
||||
platformTransformers: [require('../transformers/NativeClass').default],
|
||||
},
|
||||
]);
|
||||
|
||||
// Filter common undesirable warnings
|
||||
config.set(
|
||||
'ignoreWarnings',
|
||||
(config.get('ignoreWarnings') ?? []).concat([
|
||||
/**
|
||||
* This rule hides
|
||||
* +-----------------------------------------------------------------------------------------+
|
||||
* | WARNING in Zone.js does not support native async/await in ES2017+. |
|
||||
* | These blocks are not intercepted by zone.js and will not triggering change detection. |
|
||||
* | See: https://github.com/angular/zone.js/pull/1140 for more information. |
|
||||
* +-----------------------------------------------------------------------------------------+
|
||||
*/
|
||||
/Zone\.js does not support native async\/await/,
|
||||
/**
|
||||
* This rule hides
|
||||
* +-----------------------------------------------------------------------------------------+
|
||||
* | WARNING in environment.*.ts is part of the TypeScript compilation but it's unused. |
|
||||
* | Add only entry points to the 'files' or 'include' properties in your tsconfig. |
|
||||
* +-----------------------------------------------------------------------------------------+
|
||||
*/
|
||||
/environment.(\w+).ts is part of the TypeScript compilation but it's unused/,
|
||||
])
|
||||
);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
function getAngularCompilerPlugin() {
|
||||
const { AngularCompilerPlugin } = require('@ngtools/webpack');
|
||||
return AngularCompilerPlugin;
|
||||
}
|
374
packages/webpack5/src/configuration/base.ts
Normal file
374
packages/webpack5/src/configuration/base.ts
Normal file
@ -0,0 +1,374 @@
|
||||
import {
|
||||
ContextExclusionPlugin,
|
||||
DefinePlugin,
|
||||
HotModuleReplacementPlugin,
|
||||
} from 'webpack';
|
||||
import Config from 'webpack-chain';
|
||||
import { resolve } from 'path';
|
||||
|
||||
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
|
||||
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
||||
import TerserPlugin from 'terser-webpack-plugin';
|
||||
|
||||
import { getProjectFilePath, getProjectRootPath } from '../helpers/project';
|
||||
import { PlatformSuffixPlugin } from '../plugins/PlatformSuffixPlugin';
|
||||
import { applyFileReplacements } from '../helpers/fileReplacements';
|
||||
import { addCopyRule, applyCopyRules } from '../helpers/copyRules';
|
||||
import { WatchStatePlugin } from '../plugins/WatchStatePlugin';
|
||||
import { hasDependency } from '../helpers/dependencies';
|
||||
import { applyDotEnvPlugin } from '../helpers/dotEnv';
|
||||
import { env as _env, IWebpackEnv } from '../index';
|
||||
import { getValue } from '../helpers/config';
|
||||
import { getIPS } from '../helpers/host';
|
||||
import {
|
||||
getPlatformName,
|
||||
getAbsoluteDistPath,
|
||||
getEntryDirPath,
|
||||
getEntryPath,
|
||||
} from '../helpers/platform';
|
||||
|
||||
export default function (config: Config, env: IWebpackEnv = _env): Config {
|
||||
const entryPath = getEntryPath();
|
||||
const platform = getPlatformName();
|
||||
const mode = env.production ? 'production' : 'development';
|
||||
|
||||
// set mode
|
||||
config.mode(mode);
|
||||
|
||||
// config.stats({
|
||||
// logging: 'verbose'
|
||||
// })
|
||||
|
||||
// package.json is generated by the CLI with runtime options
|
||||
// this ensures it's not included in the bundle, but rather
|
||||
// resolved at runtime
|
||||
config.externals(['package.json', '~/package.json']);
|
||||
|
||||
// todo: devtool
|
||||
config.devtool('inline-source-map');
|
||||
|
||||
// todo: figure out easiest way to make "node" target work in ns
|
||||
// rather than the custom ns target implementation that's hard to maintain
|
||||
// appears to be working - but we still have to deal with HMR
|
||||
config.target('node');
|
||||
|
||||
config
|
||||
.entry('bundle')
|
||||
// ensure we load nativescript globals first
|
||||
.add('@nativescript/core/globals/index.js')
|
||||
.add(entryPath);
|
||||
|
||||
// Add android app components to the bundle to SBG can generate the java classes
|
||||
if (platform === 'android') {
|
||||
const appComponents = env.appComponents || [];
|
||||
appComponents.push('@nativescript/core/ui/frame');
|
||||
appComponents.push('@nativescript/core/ui/frame/activity');
|
||||
appComponents.map((component) => {
|
||||
config.entry('bundle').add(component);
|
||||
});
|
||||
}
|
||||
|
||||
// inspector_modules
|
||||
config.when(shouldIncludeInspectorModules(), (config) => {
|
||||
config
|
||||
.entry('tns_modules/inspector_modules')
|
||||
.add('@nativescript/core/inspector_modules');
|
||||
});
|
||||
|
||||
config.output
|
||||
.path(getAbsoluteDistPath())
|
||||
.pathinfo(false)
|
||||
.publicPath('')
|
||||
.libraryTarget('commonjs')
|
||||
.globalObject('global')
|
||||
.set('clean', true);
|
||||
|
||||
config.watchOptions({
|
||||
ignored: [
|
||||
`${getProjectFilePath('platforms')}/**`,
|
||||
`${env.appResourcesPath ?? getProjectFilePath('App_Resources')}/**`,
|
||||
],
|
||||
});
|
||||
|
||||
// Set up Terser options
|
||||
config.optimization.minimizer('TerserPlugin').use(TerserPlugin, [
|
||||
{
|
||||
terserOptions: {
|
||||
compress: {
|
||||
collapse_vars: platform !== 'android',
|
||||
sequences: platform !== 'android',
|
||||
keep_infinity: true,
|
||||
drop_console: mode === 'production',
|
||||
global_defs: {
|
||||
__UGLIFIED__: true,
|
||||
},
|
||||
},
|
||||
keep_fnames: true,
|
||||
keep_classnames: true,
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
config.optimization.splitChunks({
|
||||
cacheGroups: {
|
||||
defaultVendor: {
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
priority: -10,
|
||||
name: 'vendor',
|
||||
chunks: 'all',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// look for loaders in
|
||||
// - node_modules/@nativescript/webpack/dist/loaders
|
||||
// - node_modules/@nativescript/webpack/node_modules
|
||||
// - node_modules
|
||||
// allows for cleaner rules, without having to specify full paths to loaders
|
||||
config.resolveLoader.modules
|
||||
.add(resolve(__dirname, '../loaders'))
|
||||
.add(resolve(__dirname, '../../node_modules'))
|
||||
.add(getProjectFilePath('node_modules'))
|
||||
.add('node_modules');
|
||||
|
||||
config.resolve.extensions
|
||||
.add(`.${platform}.ts`)
|
||||
.add('.ts')
|
||||
.add(`.${platform}.js`)
|
||||
.add('.js')
|
||||
.add(`.${platform}.css`)
|
||||
.add('.css')
|
||||
.add(`.${platform}.scss`)
|
||||
.add('.scss')
|
||||
.add(`.${platform}.json`)
|
||||
.add('.json');
|
||||
|
||||
// base aliases
|
||||
config.resolve.alias.set('~', getEntryDirPath()).set('@', getEntryDirPath());
|
||||
|
||||
// resolve symlinks
|
||||
config.resolve.symlinks(true);
|
||||
|
||||
// resolve modules in project node_modules first
|
||||
// then fall-back to default node resolution (up the parent folder chain)
|
||||
config.resolve.modules
|
||||
.add(getProjectFilePath('node_modules'))
|
||||
.add('node_modules');
|
||||
|
||||
config.module
|
||||
.rule('bundle')
|
||||
.enforce('post')
|
||||
.test(entryPath)
|
||||
.use('app-css-loader')
|
||||
.loader('app-css-loader')
|
||||
.options({
|
||||
platform,
|
||||
})
|
||||
.end()
|
||||
.use('nativescript-hot-loader')
|
||||
.loader('nativescript-hot-loader')
|
||||
.options({
|
||||
injectHMRRuntime: true,
|
||||
});
|
||||
|
||||
// set up ts support
|
||||
config.module
|
||||
.rule('ts')
|
||||
.test([/\.ts$/])
|
||||
.use('ts-loader')
|
||||
.loader('ts-loader')
|
||||
.options({
|
||||
// todo: perhaps we can provide a default tsconfig
|
||||
// and use that if the project doesn't have one?
|
||||
// configFile: '',
|
||||
transpileOnly: true,
|
||||
allowTsInNodeModules: true,
|
||||
compilerOptions: {
|
||||
sourceMap: true,
|
||||
declaration: false,
|
||||
},
|
||||
getCustomTransformers() {
|
||||
return {
|
||||
before: [require('../transformers/NativeClass').default],
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
// Use Fork TS Checker to do type checking in a separate non-blocking process
|
||||
config.when(hasDependency('typescript'), (config) => {
|
||||
config
|
||||
.plugin('ForkTsCheckerWebpackPlugin')
|
||||
.use(ForkTsCheckerWebpackPlugin, [
|
||||
{
|
||||
typescript: {
|
||||
memoryLimit: 4096,
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
// set up js
|
||||
// todo: do we need babel-loader? It's useful to support it
|
||||
config.module
|
||||
.rule('js')
|
||||
.test(/\.js$/)
|
||||
.exclude.add(/node_modules/)
|
||||
.end()
|
||||
.use('babel-loader')
|
||||
.loader('babel-loader')
|
||||
.options({
|
||||
generatorOpts: {
|
||||
compact: false,
|
||||
},
|
||||
});
|
||||
|
||||
config.module
|
||||
.rule('workers')
|
||||
.test(/\.(js|ts)$/)
|
||||
.exclude.add(/node_modules/)
|
||||
.end()
|
||||
.use('nativescript-worker-loader')
|
||||
.loader('nativescript-worker-loader');
|
||||
|
||||
// default PostCSS options to use
|
||||
// projects can change settings
|
||||
// via postcss.config.js
|
||||
const postCSSOptions = {
|
||||
postcssOptions: {
|
||||
plugins: [
|
||||
// inlines @imported stylesheets
|
||||
'postcss-import',
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
// set up css
|
||||
config.module
|
||||
.rule('css')
|
||||
.test(/\.css$/)
|
||||
.use('apply-css-loader')
|
||||
.loader('apply-css-loader')
|
||||
.end()
|
||||
.use('css2json-loader')
|
||||
.loader('css2json-loader')
|
||||
.end()
|
||||
.use('postcss-loader')
|
||||
.loader('postcss-loader')
|
||||
.options(postCSSOptions);
|
||||
|
||||
// set up scss
|
||||
config.module
|
||||
.rule('scss')
|
||||
.test(/\.scss$/)
|
||||
.use('apply-css-loader')
|
||||
.loader('apply-css-loader')
|
||||
.end()
|
||||
.use('css2json-loader')
|
||||
.loader('css2json-loader')
|
||||
.end()
|
||||
.use('postcss-loader')
|
||||
.loader('postcss-loader')
|
||||
.options(postCSSOptions)
|
||||
.end()
|
||||
.use('sass-loader')
|
||||
.loader('sass-loader');
|
||||
|
||||
// config.plugin('NormalModuleReplacementPlugin').use(NormalModuleReplacementPlugin, [
|
||||
// /.*/,
|
||||
// request => {
|
||||
// if (new RegExp(`\.${platform}\..+$`).test(request.request)) {
|
||||
// request.rawRequest = request.rawRequest.replace(`.${platform}.`, '.')
|
||||
// console.log(request)
|
||||
// }
|
||||
// }
|
||||
// ])
|
||||
|
||||
config.plugin('PlatformSuffixPlugin').use(PlatformSuffixPlugin, [
|
||||
{
|
||||
platform,
|
||||
},
|
||||
]);
|
||||
|
||||
// Makes sure that require.context will never include
|
||||
// App_Resources, regardless where they are located.
|
||||
config
|
||||
.plugin('ContextExclusionPlugin|App_Resources')
|
||||
.use(ContextExclusionPlugin, [new RegExp(`(.*)App_Resources(.*)`)]);
|
||||
|
||||
// Filter common undesirable warnings
|
||||
config.set(
|
||||
'ignoreWarnings',
|
||||
(config.get('ignoreWarnings') ?? []).concat([
|
||||
/**
|
||||
* This rule hides
|
||||
* +-----------------------------------------------------------------------------------------+
|
||||
* | WARNING in ./node_modules/@angular/core/fesm2015/core.js 29714:15-102 |
|
||||
* | System.import() is deprecated and will be removed soon. Use import() instead. |
|
||||
* | For more info visit https://webpack.js.org/guides/code-splitting/ |
|
||||
* +-----------------------------------------------------------------------------------------+
|
||||
*/
|
||||
/System.import\(\) is deprecated/,
|
||||
])
|
||||
);
|
||||
|
||||
// todo: refine defaults
|
||||
config.plugin('DefinePlugin').use(DefinePlugin, [
|
||||
{
|
||||
__DEV__: mode === 'development',
|
||||
__NS_WEBPACK__: true,
|
||||
__NS_ENV_VERBOSE__: !!env.verbose,
|
||||
__NS_DEV_HOST_IPS__:
|
||||
mode === 'development' ? JSON.stringify(getIPS()) : `[]`,
|
||||
__CSS_PARSER__: JSON.stringify(getValue('cssParser', 'css-tree')),
|
||||
__ANDROID__: platform === 'android',
|
||||
__IOS__: platform === 'ios',
|
||||
/* for compat only */ 'global.isAndroid': platform === 'android',
|
||||
/* for compat only */ 'global.isIOS': platform === 'ios',
|
||||
process: 'global.process',
|
||||
|
||||
// todo: ?!?!
|
||||
// profile: '() => {}',
|
||||
},
|
||||
]);
|
||||
|
||||
// enable DotEnv
|
||||
applyDotEnvPlugin(config);
|
||||
|
||||
// replacements
|
||||
applyFileReplacements(config);
|
||||
|
||||
// set up default copy rules
|
||||
addCopyRule('assets/**');
|
||||
addCopyRule('fonts/**');
|
||||
addCopyRule('**/*.+(jpg|png)');
|
||||
|
||||
applyCopyRules(config);
|
||||
|
||||
config.plugin('WatchStatePlugin').use(WatchStatePlugin);
|
||||
|
||||
config.when(env.hmr, (config) => {
|
||||
config.plugin('HotModuleReplacementPlugin').use(HotModuleReplacementPlugin);
|
||||
});
|
||||
|
||||
config.when(env.report, (config) => {
|
||||
const projectRoot = getProjectRootPath();
|
||||
config.plugin('BundleAnalyzerPlugin').use(BundleAnalyzerPlugin, [
|
||||
{
|
||||
analyzerMode: 'static',
|
||||
generateStatsFile: true,
|
||||
openAnalyzer: false,
|
||||
reportFilename: resolve(projectRoot, 'report', 'report.html'),
|
||||
statsFilename: resolve(projectRoot, 'report', 'stats.json'),
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
function shouldIncludeInspectorModules(): boolean {
|
||||
const platform = getPlatformName();
|
||||
// todo: check if core modules are external
|
||||
// todo: check if we are testing
|
||||
return platform === 'ios';
|
||||
}
|
18
packages/webpack5/src/configuration/index.ts
Normal file
18
packages/webpack5/src/configuration/index.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import base from './base';
|
||||
|
||||
import angular from './angular';
|
||||
import javascript from './javascript';
|
||||
import react from './react';
|
||||
import svelte from './svelte';
|
||||
import typescript from './typescript';
|
||||
import vue from './vue';
|
||||
|
||||
export const configs = {
|
||||
base,
|
||||
angular,
|
||||
javascript,
|
||||
react,
|
||||
svelte,
|
||||
typescript,
|
||||
vue,
|
||||
};
|
49
packages/webpack5/src/configuration/javascript.ts
Normal file
49
packages/webpack5/src/configuration/javascript.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import Config from 'webpack-chain';
|
||||
|
||||
import { getEntryPath, getEntryDirPath } from '../helpers/platform';
|
||||
import { addVirtualEntry } from '../helpers/virtualModules';
|
||||
import { env as _env, IWebpackEnv } from '../index';
|
||||
import base from './base';
|
||||
|
||||
export default function (config: Config, env: IWebpackEnv = _env): Config {
|
||||
base(config, env);
|
||||
const entryPath = getEntryPath();
|
||||
const filterRE = '/.(xml|js|s?css)$/';
|
||||
const virtualEntryPath = addVirtualEntry(
|
||||
config,
|
||||
'javascript',
|
||||
`
|
||||
// VIRTUAL ENTRY START
|
||||
require('@nativescript/core/bundle-entry-points')
|
||||
const context = require.context("~/", /* deep: */ true, /* filter: */ ${filterRE});
|
||||
global.registerWebpackModules(context);
|
||||
// VIRTUAL ENTRY END
|
||||
`
|
||||
);
|
||||
|
||||
config.entry('bundle').add(virtualEntryPath);
|
||||
|
||||
// config.resolve.extensions.add('.xml');
|
||||
|
||||
// set up xml
|
||||
config.module
|
||||
.rule('xml')
|
||||
.test(/\.xml$/)
|
||||
.use('xml-namespace-loader')
|
||||
.loader('xml-namespace-loader');
|
||||
|
||||
// set up core HMR
|
||||
config.module
|
||||
.rule('hmr-core')
|
||||
.test(/\.js$/)
|
||||
.exclude.add(/node_modules/)
|
||||
.add(entryPath)
|
||||
.end()
|
||||
.use('nativescript-hot-loader')
|
||||
.loader('nativescript-hot-loader')
|
||||
.options({
|
||||
appPath: getEntryDirPath(),
|
||||
});
|
||||
|
||||
return config;
|
||||
}
|
72
packages/webpack5/src/configuration/react.ts
Normal file
72
packages/webpack5/src/configuration/react.ts
Normal file
@ -0,0 +1,72 @@
|
||||
import { merge } from 'webpack-merge';
|
||||
import Config from 'webpack-chain';
|
||||
|
||||
import { getPlatformName } from '../helpers/platform';
|
||||
import { env as _env, IWebpackEnv } from '../index';
|
||||
import base from './base';
|
||||
|
||||
export default function (config: Config, env: IWebpackEnv = _env): Config {
|
||||
base(config, env);
|
||||
|
||||
const platform = getPlatformName();
|
||||
const mode = env.production ? 'production' : 'development';
|
||||
const production = mode === 'production';
|
||||
|
||||
// todo: use env
|
||||
let isAnySourceMapEnabled = true;
|
||||
|
||||
config.resolve.extensions.prepend('.tsx').prepend(`.${platform}.tsx`);
|
||||
config.resolve.alias.set('react-dom', 'react-nativescript');
|
||||
|
||||
config.module
|
||||
.rule('ts')
|
||||
.test([...config.module.rule('ts').get('test'), /\.tsx$/]);
|
||||
|
||||
config.plugin('DefinePlugin').tap((args) => {
|
||||
args[0] = merge(args[0], {
|
||||
/** For various libraries in the React ecosystem. */
|
||||
__TEST__: false,
|
||||
/**
|
||||
* Primarily for React Fast Refresh plugin, but technically the allowHmrInProduction option could be used instead.
|
||||
* Worth including anyway, as there are plenty of Node libraries that use this flag.
|
||||
*/
|
||||
'process.env.NODE_ENV': JSON.stringify(mode),
|
||||
});
|
||||
|
||||
return args;
|
||||
});
|
||||
|
||||
// todo: env flag to forceEnable?
|
||||
config.when(env.hmr && !production, (config) => {
|
||||
config.module
|
||||
.rule('ts')
|
||||
.use('babel-loader|react-refresh')
|
||||
.loader('babel-loader')
|
||||
.before('ts-loader')
|
||||
.options({
|
||||
sourceMaps: isAnySourceMapEnabled ? 'inline' : false,
|
||||
babelrc: false,
|
||||
plugins: ['react-refresh/babel'],
|
||||
});
|
||||
|
||||
config
|
||||
.plugin('ReactRefreshPlugin')
|
||||
.use(require('@pmmmwh/react-refresh-webpack-plugin'), [
|
||||
{
|
||||
/**
|
||||
* Maybe one day we'll implement an Error Overlay, but the work involved is too daunting for now.
|
||||
* @see https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/79#issuecomment-644324557
|
||||
*/
|
||||
overlay: false,
|
||||
/**
|
||||
* If you (temporarily) want to enable HMR on a production build:
|
||||
* 1) Set `forceEnable` to `true`
|
||||
* 2) Remove the `!production` condition on `tsxRule` to ensure that babel-loader gets used.
|
||||
*/
|
||||
forceEnable: false,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
return config;
|
||||
}
|
65
packages/webpack5/src/configuration/svelte.ts
Normal file
65
packages/webpack5/src/configuration/svelte.ts
Normal file
@ -0,0 +1,65 @@
|
||||
import Config from 'webpack-chain';
|
||||
|
||||
import { getProjectFilePath, getProjectRootPath } from '../helpers/project';
|
||||
import { getPlatformName } from '../helpers/platform';
|
||||
import { env as _env, IWebpackEnv } from '../index';
|
||||
import { error } from '../helpers/log';
|
||||
import base from './base';
|
||||
|
||||
export default function (config: Config, env: IWebpackEnv = _env): Config {
|
||||
base(config, env);
|
||||
|
||||
const platform = getPlatformName();
|
||||
const mode = env.production ? 'production' : 'development';
|
||||
const production = mode === 'production';
|
||||
|
||||
// resolve .svelte files
|
||||
// the order is reversed because we are using prepend!
|
||||
config.resolve.extensions.prepend('.svelte').prepend(`.${platform}.svelte`);
|
||||
// add a rule for .svelte files
|
||||
config.module
|
||||
.rule('svelte')
|
||||
.test(/\.svelte$/)
|
||||
.exclude.add(/node_modules/)
|
||||
.end()
|
||||
.use('svelte-loader-hot')
|
||||
.loader('svelte-loader-hot')
|
||||
.tap((options) => {
|
||||
return {
|
||||
...options,
|
||||
dev: !production,
|
||||
preprocess: getSvelteConfigPreprocessor(),
|
||||
hotReload: !production,
|
||||
hotOptions: {
|
||||
injectCss: false,
|
||||
native: true,
|
||||
},
|
||||
// Suppress A11y warnings
|
||||
onwarn(warning, warn) {
|
||||
if (!/A11y:/.test(warning.message)) {
|
||||
warn(warning);
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
function getSvelteConfigPreprocessor(): any {
|
||||
const config = getSvelteConfig();
|
||||
|
||||
return config?.preprocess;
|
||||
}
|
||||
|
||||
interface ISvelteConfig {
|
||||
preprocess: any;
|
||||
}
|
||||
|
||||
function getSvelteConfig(): ISvelteConfig | undefined {
|
||||
try {
|
||||
return require(getProjectFilePath('svelte.config.js')) as ISvelteConfig;
|
||||
} catch (err) {
|
||||
error('Could not find svelte.config.js.', err);
|
||||
}
|
||||
}
|
49
packages/webpack5/src/configuration/typescript.ts
Normal file
49
packages/webpack5/src/configuration/typescript.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import Config from 'webpack-chain';
|
||||
|
||||
import { getEntryDirPath, getEntryPath } from '../helpers/platform';
|
||||
import { addVirtualEntry } from '../helpers/virtualModules';
|
||||
import { env as _env, IWebpackEnv } from '../index';
|
||||
import base from './base';
|
||||
|
||||
export default function (config: Config, env: IWebpackEnv = _env): Config {
|
||||
base(config, env);
|
||||
const entryPath = getEntryPath();
|
||||
const filterRE = '/\\.(xml|js|(?<!d\\.)ts|s?css)$/';
|
||||
const virtualEntryPath = addVirtualEntry(
|
||||
config,
|
||||
'typescript',
|
||||
`
|
||||
// VIRTUAL ENTRY START
|
||||
require('@nativescript/core/bundle-entry-points')
|
||||
const context = require.context("~/", /* deep: */ true, /* filter: */ ${filterRE});
|
||||
global.registerWebpackModules(context);
|
||||
// VIRTUAL ENTRY END
|
||||
`
|
||||
);
|
||||
|
||||
config.entry('bundle').add(virtualEntryPath);
|
||||
|
||||
// config.resolve.extensions.add('.xml');
|
||||
|
||||
// set up xml
|
||||
config.module
|
||||
.rule('xml')
|
||||
.test(/\.xml$/)
|
||||
.use('xml-namespace-loader')
|
||||
.loader('xml-namespace-loader');
|
||||
|
||||
// set up core HMR
|
||||
config.module
|
||||
.rule('hmr-core')
|
||||
.test(/\.(js|ts)$/)
|
||||
.exclude.add(/node_modules/)
|
||||
.add(entryPath)
|
||||
.end()
|
||||
.use('nativescript-hot-loader')
|
||||
.loader('nativescript-hot-loader')
|
||||
.options({
|
||||
appPath: getEntryDirPath(),
|
||||
});
|
||||
|
||||
return config;
|
||||
}
|
96
packages/webpack5/src/configuration/vue.ts
Normal file
96
packages/webpack5/src/configuration/vue.ts
Normal file
@ -0,0 +1,96 @@
|
||||
import { VueLoaderPlugin } from 'vue-loader';
|
||||
import { merge } from 'webpack-merge';
|
||||
import Config from 'webpack-chain';
|
||||
import fs from 'fs';
|
||||
|
||||
import { hasDependency } from '../helpers/dependencies';
|
||||
import { getPlatformName } from '../helpers/platform';
|
||||
import { env as _env, IWebpackEnv } from '../index';
|
||||
import { error } from '../helpers/log';
|
||||
import base from './base';
|
||||
|
||||
export default function (config: Config, env: IWebpackEnv = _env): Config {
|
||||
base(config, env);
|
||||
|
||||
const platform = getPlatformName();
|
||||
|
||||
// we need to patch VueLoader if we want to enable hmr
|
||||
if (env.hmr) {
|
||||
patchVueLoaderForHMR();
|
||||
}
|
||||
|
||||
// resolve .vue files
|
||||
// the order is reversed because we are using prepend!
|
||||
config.resolve.extensions.prepend('.vue').prepend(`.${platform}.vue`);
|
||||
|
||||
// add a rule for .vue files
|
||||
config.module
|
||||
.rule('vue')
|
||||
.test(/\.vue$/)
|
||||
.use('vue-loader')
|
||||
.loader('vue-loader')
|
||||
.tap((options) => {
|
||||
return {
|
||||
...options,
|
||||
compiler: require('nativescript-vue-template-compiler'),
|
||||
};
|
||||
});
|
||||
|
||||
// set up ts support in vue files
|
||||
config.module
|
||||
.rule('ts')
|
||||
.use('ts-loader')
|
||||
.loader('ts-loader')
|
||||
.tap((options = {}) => {
|
||||
return merge(options, {
|
||||
appendTsSuffixTo: ['\\.vue$'],
|
||||
});
|
||||
});
|
||||
|
||||
config.when(hasDependency('typescript'), (config) => {
|
||||
config.plugin('ForkTsCheckerWebpackPlugin').tap((args) => {
|
||||
args[0] = merge(args[0], {
|
||||
typescript: {
|
||||
extensions: {
|
||||
vue: {
|
||||
enabled: true,
|
||||
compiler: 'nativescript-vue-template-compiler',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
return args;
|
||||
});
|
||||
});
|
||||
|
||||
// add VueLoaderPlugin as the first plugin
|
||||
config
|
||||
.plugin('VueLoaderPlugin')
|
||||
// @ts-ignore
|
||||
.before(config.plugins.values()[0].name)
|
||||
.use(VueLoaderPlugin);
|
||||
|
||||
// add an alias for vue, since some plugins may try to import it
|
||||
config.resolve.alias.set('vue', 'nativescript-vue');
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patches source of vue-loader to set the isServer flag to false
|
||||
* so hmr gets enabled.
|
||||
*/
|
||||
function patchVueLoaderForHMR() {
|
||||
try {
|
||||
const vueLoaderPath = require.resolve('vue-loader/lib/index.js');
|
||||
const source = fs.readFileSync(vueLoaderPath).toString();
|
||||
const patchedSource = source.replace(
|
||||
/(isServer\s=\s)(target\s===\s'node')/g,
|
||||
'$1false;'
|
||||
);
|
||||
fs.writeFileSync(vueLoaderPath, patchedSource);
|
||||
delete require.cache[vueLoaderPath];
|
||||
} catch (err) {
|
||||
error('Failed to patch VueLoader - HMR may not work properly!');
|
||||
}
|
||||
}
|
1
packages/webpack5/src/globals.d.ts
vendored
Normal file
1
packages/webpack5/src/globals.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
// define globals here
|
34
packages/webpack5/src/helpers/config.ts
Normal file
34
packages/webpack5/src/helpers/config.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { env } from '../index';
|
||||
import { error, warnOnce } from './log';
|
||||
|
||||
function getCLILib() {
|
||||
if (!env.nativescriptLibPath) {
|
||||
warnOnce(
|
||||
'getCLILib',
|
||||
`
|
||||
Cannot find NativeScript CLI path. Make sure --env.nativescriptLibPath is passed
|
||||
`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return require(env.nativescriptLibPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to get a value from the nativescript.config.ts file.
|
||||
*
|
||||
* @param {string} key The key to get from the config. Supports dot-notation.
|
||||
* @param defaultValue The fallback value if the key is not set in the config.
|
||||
*/
|
||||
export function getValue<T = any>(key: string, defaultValue?: any): T {
|
||||
const lib = getCLILib();
|
||||
|
||||
if (!lib) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return (lib.projectConfigService as {
|
||||
getValue(key: string, defaultValue?: any): T;
|
||||
}).getValue(key, defaultValue);
|
||||
}
|
85
packages/webpack5/src/helpers/copyRules.ts
Normal file
85
packages/webpack5/src/helpers/copyRules.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import CopyWebpackPlugin from 'copy-webpack-plugin';
|
||||
import { relative, resolve } from 'path';
|
||||
import Config from 'webpack-chain';
|
||||
|
||||
import { getProjectRootPath } from './project';
|
||||
import { getEntryDirPath } from './platform';
|
||||
import { env } from '..';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export let copyRules = new Set([]);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export let additionalCopyRules = [];
|
||||
|
||||
/**
|
||||
* Utility to add new copy rules. Accepts a glob or an object. For example
|
||||
* - **\/*.html - copy all .html files found in any sub dir.
|
||||
* - myFolder/* - copy all files from myFolder
|
||||
*
|
||||
* When passing an object - no additional processing is done, and it's
|
||||
* applied as-is. Make sure to set every required property.
|
||||
*
|
||||
* The path is relative to the folder of the entry file
|
||||
* (specified in the main field of the package.json)
|
||||
*
|
||||
* @param {string|object} globOrObject
|
||||
*/
|
||||
export function addCopyRule(globOrObject: string | object) {
|
||||
if (typeof globOrObject === 'string') {
|
||||
return copyRules.add(globOrObject);
|
||||
}
|
||||
|
||||
additionalCopyRules.push(globOrObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to remove a copy rule. The glob should be the exact glob
|
||||
* to remove. For example
|
||||
* - fonts/** - to remove the default copy rule for fonts
|
||||
*
|
||||
* @param {string} glob
|
||||
*/
|
||||
export function removeCopyRule(glob: string) {
|
||||
copyRules.delete(glob);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function applyCopyRules(config: Config) {
|
||||
const entryDir = getEntryDirPath();
|
||||
const globOptions = {
|
||||
dot: false,
|
||||
ignore: [],
|
||||
};
|
||||
|
||||
// todo: do we need to handle empty appResourcesPath?
|
||||
// (the CLI should always pass the path - maybe not required)
|
||||
if (env.appResourcesPath) {
|
||||
const appResourcesFullPath = resolve(
|
||||
getProjectRootPath(),
|
||||
env.appResourcesPath
|
||||
);
|
||||
|
||||
// ignore everything in App_Resources (regardless where they are located)
|
||||
globOptions.ignore.push(`${relative(entryDir, appResourcesFullPath)}/**`);
|
||||
}
|
||||
|
||||
config.plugin('CopyWebpackPlugin').use(CopyWebpackPlugin, [
|
||||
{
|
||||
patterns: Array.from(copyRules)
|
||||
.map((glob) => ({
|
||||
from: glob,
|
||||
context: entryDir,
|
||||
noErrorOnMissing: true,
|
||||
globOptions,
|
||||
}))
|
||||
.concat(additionalCopyRules),
|
||||
},
|
||||
]);
|
||||
}
|
49
packages/webpack5/src/helpers/dependencies.ts
Normal file
49
packages/webpack5/src/helpers/dependencies.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import path from 'path';
|
||||
|
||||
import { getPackageJson, getProjectRootPath } from './project';
|
||||
|
||||
// todo: memoize
|
||||
/**
|
||||
* Utility to get all dependencies from the project package.json.
|
||||
* The result combines dependencies and devDependencies
|
||||
*
|
||||
* @returns string[] dependencies
|
||||
*/
|
||||
export function getAllDependencies(): string[] {
|
||||
const packageJSON = getPackageJson();
|
||||
|
||||
return [
|
||||
...Object.keys(packageJSON.dependencies ?? {}),
|
||||
...Object.keys(packageJSON.devDependencies ?? {}),
|
||||
];
|
||||
}
|
||||
|
||||
// todo: memoize
|
||||
/**
|
||||
* Utility to check if the project has a specific dependency
|
||||
* in either dependencies or devDependencies.
|
||||
*
|
||||
* @param {string} dependencyName
|
||||
* @returns boolean
|
||||
*/
|
||||
export function hasDependency(dependencyName: string) {
|
||||
return getAllDependencies().includes(dependencyName);
|
||||
}
|
||||
|
||||
// todo: memoize
|
||||
/**
|
||||
* Utility to get the path (usually nested in node_modules) of a dependency.
|
||||
*
|
||||
* @param dependencyName
|
||||
*/
|
||||
export function getDependencyPath(dependencyName: string): string | null {
|
||||
try {
|
||||
const resolvedPath = require.resolve(`${dependencyName}/package.json`, {
|
||||
paths: [getProjectRootPath()],
|
||||
});
|
||||
|
||||
return path.dirname(resolvedPath);
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
}
|
49
packages/webpack5/src/helpers/dotEnv.ts
Normal file
49
packages/webpack5/src/helpers/dotEnv.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import DotEnvPlugin from 'dotenv-webpack';
|
||||
import Config from 'webpack-chain';
|
||||
import { existsSync } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
|
||||
import { getProjectRootPath } from './project';
|
||||
import { env } from '..';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function applyDotEnvPlugin(config: Config) {
|
||||
const path = getDotEnvPath();
|
||||
|
||||
config.when(path !== null, (config) => {
|
||||
config.plugin('DotEnvPlugin').use(DotEnvPlugin, [
|
||||
{
|
||||
path,
|
||||
silent: true, // hide any errors
|
||||
},
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
function getDotEnvFileName(): string {
|
||||
if (env.env) {
|
||||
return `.env.${env.env}`;
|
||||
}
|
||||
|
||||
return '.env';
|
||||
}
|
||||
|
||||
function getDotEnvPath(): string {
|
||||
const dotEnvPath = resolve(getProjectRootPath(), '.env');
|
||||
const dotEnvWithEnvPath = resolve(getProjectRootPath(), getDotEnvFileName());
|
||||
|
||||
// look for .env.<env>
|
||||
if (existsSync(dotEnvWithEnvPath)) {
|
||||
return dotEnvWithEnvPath;
|
||||
}
|
||||
|
||||
// fall back to .env
|
||||
if (existsSync(dotEnvPath)) {
|
||||
return dotEnvPath;
|
||||
}
|
||||
|
||||
// don't use .env
|
||||
return null;
|
||||
}
|
49
packages/webpack5/src/helpers/externalConfigs.ts
Normal file
49
packages/webpack5/src/helpers/externalConfigs.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
import { getAllDependencies, getDependencyPath } from './dependencies';
|
||||
import { clearCurrentPlugin, setCurrentPlugin } from '../index';
|
||||
import { info, warn } from './log';
|
||||
import * as lib from '../index';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function applyExternalConfigs() {
|
||||
getAllDependencies().forEach((dependency) => {
|
||||
const packagePath = getDependencyPath(dependency);
|
||||
|
||||
if (!packagePath) {
|
||||
return;
|
||||
}
|
||||
|
||||
const configPath = path.join(packagePath, 'nativescript.webpack.js');
|
||||
|
||||
if (fs.existsSync(configPath)) {
|
||||
info(`Discovered config: ${configPath}`);
|
||||
setCurrentPlugin(dependency);
|
||||
try {
|
||||
const externalConfig = require(configPath);
|
||||
|
||||
if (typeof externalConfig === 'function') {
|
||||
info('Applying external config...');
|
||||
externalConfig(lib);
|
||||
} else if (externalConfig) {
|
||||
info('Merging external config...');
|
||||
lib.mergeWebpack(externalConfig);
|
||||
} else {
|
||||
warn(
|
||||
'Unsupported external config. The config must export a function or an object.'
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
warn(`
|
||||
Unable to apply config: ${configPath}.
|
||||
Error is: ${err}
|
||||
`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
clearCurrentPlugin();
|
||||
}
|
68
packages/webpack5/src/helpers/fileReplacements.ts
Normal file
68
packages/webpack5/src/helpers/fileReplacements.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import { resolve } from 'path';
|
||||
|
||||
import { env as _env, IWebpackEnv } from '../index';
|
||||
import { addCopyRule } from './copyRules';
|
||||
import { getProjectRootPath } from './project';
|
||||
|
||||
interface IReplacementMap {
|
||||
[_replace: string]: /* _with */ string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function getFileReplacementsFromEnv(
|
||||
env: IWebpackEnv = _env
|
||||
): IReplacementMap {
|
||||
const fileReplacements: IReplacementMap = {};
|
||||
|
||||
const entries: string[] = (() => {
|
||||
if (Array.isArray(env.replace)) {
|
||||
return env.replace;
|
||||
}
|
||||
|
||||
if (typeof env.replace === 'string') {
|
||||
return [env.replace];
|
||||
}
|
||||
|
||||
return [];
|
||||
})();
|
||||
|
||||
entries.forEach((replaceEntry) => {
|
||||
replaceEntry.split(/,\s*/).forEach((r: string) => {
|
||||
let [_replace, _with] = r.split(':');
|
||||
|
||||
if (!_replace || !_with) {
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure to resolve replacements to a full path
|
||||
// relative to the project root
|
||||
_replace = resolve(getProjectRootPath(), _replace);
|
||||
_with = resolve(getProjectRootPath(), _with);
|
||||
|
||||
fileReplacements[_replace] = _with;
|
||||
});
|
||||
});
|
||||
|
||||
return fileReplacements;
|
||||
}
|
||||
|
||||
export function applyFileReplacements(
|
||||
config,
|
||||
fileReplacements: IReplacementMap = getFileReplacementsFromEnv()
|
||||
) {
|
||||
Object.entries(fileReplacements).forEach(([_replace, _with]) => {
|
||||
// in case we are replacing source files - we'll use aliases
|
||||
if (_replace.match(/\.(ts|js)$/)) {
|
||||
return config.resolve.alias.set(_replace, _with);
|
||||
}
|
||||
|
||||
// otherwise we will override the replaced file with the replacement
|
||||
addCopyRule({
|
||||
from: _with, // copy the replacement file
|
||||
to: _replace, // to the original "to-be-replaced" file
|
||||
force: true,
|
||||
});
|
||||
});
|
||||
}
|
47
packages/webpack5/src/helpers/flavor.ts
Normal file
47
packages/webpack5/src/helpers/flavor.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { defaultConfigs } from '@nativescript/webpack';
|
||||
import { getAllDependencies } from './dependencies';
|
||||
import { error } from './log';
|
||||
|
||||
/**
|
||||
* Utility to determine the project flavor based on installed dependencies
|
||||
* (vue, angular, react, svelete, typescript, javascript...)
|
||||
*/
|
||||
export function determineProjectFlavor(): keyof typeof defaultConfigs | false {
|
||||
const dependencies = getAllDependencies();
|
||||
|
||||
if (dependencies.includes('nativescript-vue')) {
|
||||
return 'vue';
|
||||
}
|
||||
|
||||
if (dependencies.includes('@nativescript/angular')) {
|
||||
return 'angular';
|
||||
}
|
||||
|
||||
if (dependencies.includes('react-nativescript')) {
|
||||
return 'react';
|
||||
}
|
||||
|
||||
if (dependencies.includes('svelte-native')) {
|
||||
return 'svelte';
|
||||
}
|
||||
|
||||
// the order is important - angular, react, and svelte also include these deps
|
||||
// but should return prior to this condition!
|
||||
if (
|
||||
dependencies.includes('@nativescript/core') &&
|
||||
dependencies.includes('typescript')
|
||||
) {
|
||||
return 'typescript';
|
||||
}
|
||||
|
||||
if (dependencies.includes('@nativescript/core')) {
|
||||
return 'javascript';
|
||||
}
|
||||
|
||||
error(`
|
||||
Could not determine project flavor.
|
||||
Please use webpack.useConfig('<flavor>') to explicitly set the base config.
|
||||
`);
|
||||
|
||||
return false;
|
||||
}
|
13
packages/webpack5/src/helpers/host.ts
Normal file
13
packages/webpack5/src/helpers/host.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import os from 'os';
|
||||
|
||||
export function getIPS() {
|
||||
const interfaces = os.networkInterfaces();
|
||||
return Object.keys(interfaces)
|
||||
.map((name) => {
|
||||
return interfaces[name].filter(
|
||||
(binding: any) => binding.family === 'IPv4'
|
||||
)[0];
|
||||
})
|
||||
.filter(Boolean)
|
||||
.map((binding) => binding.address);
|
||||
}
|
78
packages/webpack5/src/helpers/index.ts
Normal file
78
packages/webpack5/src/helpers/index.ts
Normal file
@ -0,0 +1,78 @@
|
||||
import { merge } from 'webpack-merge';
|
||||
|
||||
import {
|
||||
getPackageJson,
|
||||
getProjectRootPath,
|
||||
getProjectFilePath,
|
||||
} from './project';
|
||||
import { addVirtualEntry, addVirtualModule } from './virtualModules';
|
||||
import { applyFileReplacements } from './fileReplacements';
|
||||
import { addCopyRule, removeCopyRule } from './copyRules';
|
||||
import { error, info, warn, warnOnce } from './log';
|
||||
import { determineProjectFlavor } from './flavor';
|
||||
import { getValue } from './config';
|
||||
import { getIPS } from './host';
|
||||
import {
|
||||
getAllDependencies,
|
||||
hasDependency,
|
||||
getDependencyPath,
|
||||
} from './dependencies';
|
||||
import {
|
||||
addPlatform,
|
||||
getAbsoluteDistPath,
|
||||
getDistPath,
|
||||
getEntryDirPath,
|
||||
getEntryPath,
|
||||
getPlatform,
|
||||
getPlatformName,
|
||||
} from './platform';
|
||||
|
||||
// intentionally populated manually
|
||||
// as this generates nicer typings
|
||||
// that show all the utils inline
|
||||
// rather than imports to types
|
||||
// todo: maybe use api-extractor instead
|
||||
export default {
|
||||
merge,
|
||||
addCopyRule,
|
||||
removeCopyRule,
|
||||
applyFileReplacements,
|
||||
config: {
|
||||
getValue,
|
||||
},
|
||||
dependencies: {
|
||||
getAllDependencies,
|
||||
hasDependency,
|
||||
getDependencyPath,
|
||||
},
|
||||
flavor: {
|
||||
determineProjectFlavor,
|
||||
},
|
||||
host: {
|
||||
getIPS,
|
||||
},
|
||||
log: {
|
||||
error,
|
||||
info,
|
||||
warn,
|
||||
warnOnce,
|
||||
},
|
||||
platform: {
|
||||
addPlatform,
|
||||
getAbsoluteDistPath,
|
||||
getDistPath,
|
||||
getEntryDirPath,
|
||||
getEntryPath,
|
||||
getPlatform,
|
||||
getPlatformName,
|
||||
},
|
||||
project: {
|
||||
getProjectFilePath,
|
||||
getProjectRootPath,
|
||||
getPackageJson,
|
||||
},
|
||||
virtualModules: {
|
||||
addVirtualEntry,
|
||||
addVirtualModule,
|
||||
},
|
||||
};
|
57
packages/webpack5/src/helpers/log.ts
Normal file
57
packages/webpack5/src/helpers/log.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import dedent from 'ts-dedent';
|
||||
import { env } from '@nativescript/webpack';
|
||||
|
||||
// de-indents strings so multi-line string literals can be used
|
||||
function cleanup(data: any[]) {
|
||||
return data.map((d) => {
|
||||
if (typeof d === 'string') {
|
||||
return dedent(d);
|
||||
}
|
||||
return d;
|
||||
});
|
||||
}
|
||||
|
||||
export function error(...data: any): Error {
|
||||
console.warn(`[@nativescript/webpack] Error: \n`, ...cleanup(data));
|
||||
|
||||
// we return the error - the caller can throw or ignore
|
||||
if (typeof data[0] === 'string') {
|
||||
return new Error(
|
||||
'\n\n[@nativescript/webpack]\n---\n\n' + dedent(data[0]) + '\n\n---\n'
|
||||
);
|
||||
}
|
||||
|
||||
return new Error('@nativescript/webpack ran into a problem...');
|
||||
}
|
||||
|
||||
export function warn(...data: any): void {
|
||||
console.warn(`[@nativescript/webpack] Warn: \n`, ...cleanup(data));
|
||||
}
|
||||
|
||||
const warnedMap: any = {};
|
||||
export function warnOnce(key: string, ...data: any): void {
|
||||
if (warnedMap[key]) {
|
||||
return;
|
||||
}
|
||||
|
||||
warnedMap[key] = true;
|
||||
warn(...data);
|
||||
}
|
||||
|
||||
export function info(...data: any): void {
|
||||
if (env.verbose) {
|
||||
console.log(`[@nativescript/webpack] Info: \n`, ...cleanup(data));
|
||||
}
|
||||
}
|
||||
|
||||
// todo: refine
|
||||
// export function error(message: string, info?: { possibleCauses?: string[] }) {
|
||||
// console.error(`
|
||||
// NativeScript Webpack encountered an error and cannot proceed with the build:
|
||||
//
|
||||
// ${message}
|
||||
//
|
||||
// Possible causes:
|
||||
// ${info?.possibleCauses?.map((cause) => `- ${cause}`).join('\n')}
|
||||
// `);
|
||||
// }
|
128
packages/webpack5/src/helpers/platform.ts
Normal file
128
packages/webpack5/src/helpers/platform.ts
Normal file
@ -0,0 +1,128 @@
|
||||
import { dirname, resolve } from 'path';
|
||||
|
||||
import { getPackageJson, getProjectRootPath } from './project';
|
||||
import { error, info, warnOnce } from './log';
|
||||
import { env } from '../';
|
||||
|
||||
import AndroidPlatform from '../platforms/android';
|
||||
import iOSPlatform from '../platforms/ios';
|
||||
|
||||
export interface INativeScriptPlatform {
|
||||
getEntryPath?(): string;
|
||||
|
||||
getDistPath?(): string;
|
||||
}
|
||||
|
||||
export type Platform = Extract<keyof typeof platforms, string>;
|
||||
|
||||
const platforms: {
|
||||
[name: string]: INativeScriptPlatform;
|
||||
} = {
|
||||
android: AndroidPlatform,
|
||||
ios: iOSPlatform,
|
||||
};
|
||||
|
||||
/**
|
||||
* Utility to register a new supported platform.
|
||||
*
|
||||
* @param {string} name The name of the platform (eg. web, desktop)
|
||||
* @param platform A platform definition of the platform specifics
|
||||
*/
|
||||
export function addPlatform(name: string, platform: INativeScriptPlatform) {
|
||||
info(`Adding platform ${name}`, platform);
|
||||
platforms[name] = platform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to get the currently targeted platform definition
|
||||
*/
|
||||
export function getPlatform(): INativeScriptPlatform {
|
||||
return platforms[getPlatformName()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to get the currently targeted platform name
|
||||
*/
|
||||
export function getPlatformName(): Platform {
|
||||
if (env?.android) {
|
||||
return 'android';
|
||||
}
|
||||
|
||||
if (env?.ios) {
|
||||
return 'ios';
|
||||
}
|
||||
|
||||
// support custom platforms
|
||||
if (env?.platform) {
|
||||
if (platforms[env.platform]) {
|
||||
return env.platform;
|
||||
}
|
||||
|
||||
throw error(`
|
||||
Invalid platform: ${env.platform}
|
||||
|
||||
Valid platforms: ${Object.keys(platforms).join(', ')}
|
||||
`);
|
||||
}
|
||||
|
||||
warnOnce(
|
||||
'getPlatformName',
|
||||
`
|
||||
You need to provide a target platform!
|
||||
|
||||
Available platforms: ${Object.keys(platforms).join(', ')}
|
||||
|
||||
Use --env.platform=<platform> or --env.android, --env.ios to specify the target platform.
|
||||
|
||||
Defaulting to "ios".
|
||||
`
|
||||
);
|
||||
|
||||
return 'ios';
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to get the entry file path for the currently targeted platform
|
||||
*/
|
||||
export function getEntryPath() {
|
||||
const platform = getPlatform();
|
||||
|
||||
// use platform specific entry path
|
||||
if (platform.getEntryPath) {
|
||||
return platform.getEntryPath();
|
||||
}
|
||||
|
||||
// fallback to main field in package.json
|
||||
const packageJson = getPackageJson();
|
||||
|
||||
return resolve(getProjectRootPath(), packageJson.main);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to get the entry file directory path for the currently targeted platform
|
||||
*/
|
||||
export function getEntryDirPath() {
|
||||
return dirname(getEntryPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to get the dist file path for the currently targeted platform
|
||||
*/
|
||||
export function getDistPath() {
|
||||
const platform = getPlatform();
|
||||
|
||||
// use platform specific entry path
|
||||
if (platform.getDistPath) {
|
||||
return platform.getDistPath();
|
||||
}
|
||||
|
||||
// fallback to a generic platforms/<platform>/dist folder
|
||||
return `platforms/${getPlatformName()}/dist`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to get the absolute dist file path for the currently targeted platform
|
||||
*/
|
||||
export function getAbsoluteDistPath() {
|
||||
return resolve(getProjectRootPath(), getDistPath());
|
||||
}
|
50
packages/webpack5/src/helpers/project.ts
Normal file
50
packages/webpack5/src/helpers/project.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { resolve } from 'path';
|
||||
|
||||
export function getProjectRootPath(): string {
|
||||
return process.cwd();
|
||||
}
|
||||
|
||||
interface IPackageJson {
|
||||
main?: string;
|
||||
dependencies?: {
|
||||
[name: string]: string;
|
||||
};
|
||||
devDependencies?: {
|
||||
[name: string]: string;
|
||||
};
|
||||
// todo: add additional fields as we require them
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to get the contents of the project package.json
|
||||
*/
|
||||
export function getPackageJson() {
|
||||
return require(getProjectFilePath('package.json')) as IPackageJson;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to get project files relative to the project root.
|
||||
* @param filePath path to get
|
||||
*/
|
||||
export function getProjectFilePath(filePath: string): string {
|
||||
return resolve(getProjectRootPath(), filePath);
|
||||
}
|
||||
|
||||
// unused helper, but keeping it here as we may need it
|
||||
// todo: remove if unused for next few releases
|
||||
// function findFile(fileName, currentDir): string | null {
|
||||
// // console.log(`findFile(${fileName}, ${currentDir})`)
|
||||
// const path = resolve(currentDir, fileName);
|
||||
//
|
||||
// if (existsSync(path)) {
|
||||
// return path;
|
||||
// }
|
||||
//
|
||||
// // bail if we reached the root dir
|
||||
// if (currentDir === resolve('/')) {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// // traverse to the parent folder
|
||||
// return findFile(fileName, resolve(currentDir, '..'));
|
||||
// }
|
49
packages/webpack5/src/helpers/virtualModules.ts
Normal file
49
packages/webpack5/src/helpers/virtualModules.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { ContextExclusionPlugin } from 'webpack';
|
||||
import Config from 'webpack-chain';
|
||||
import { join } from 'path';
|
||||
|
||||
import VirtualModulesPlugin from 'webpack-virtual-modules';
|
||||
import { getEntryDirPath } from './platform';
|
||||
import dedent from 'ts-dedent';
|
||||
|
||||
export function addVirtualEntry(
|
||||
config: Config,
|
||||
name: string,
|
||||
contents: string
|
||||
): string {
|
||||
return addVirtualModule(
|
||||
config,
|
||||
`__@nativescript_webpack_virtual_entry_${name}__`,
|
||||
contents
|
||||
);
|
||||
}
|
||||
|
||||
export function addVirtualModule(
|
||||
config: Config,
|
||||
name: string,
|
||||
contents: string
|
||||
): string {
|
||||
const virtualEntryPath = join(getEntryDirPath(), `${name}`);
|
||||
|
||||
// add the virtual entry to the context exclusions
|
||||
// makes sure that require.context will never
|
||||
// include the virtual entry.
|
||||
config
|
||||
.plugin(`ContextExclusionPlugin|${name}`)
|
||||
.use(ContextExclusionPlugin, [new RegExp(`${name}\.js$`)]);
|
||||
|
||||
const options = {
|
||||
[virtualEntryPath]: dedent(contents),
|
||||
};
|
||||
|
||||
if (config.plugins.has('VirtualModulesPlugin')) {
|
||||
config.plugin('VirtualModulesPlugin').tap((args) => {
|
||||
Object.assign(args[0], options);
|
||||
return args;
|
||||
});
|
||||
} else {
|
||||
config.plugin('VirtualModulesPlugin').use(VirtualModulesPlugin, [options]);
|
||||
}
|
||||
|
||||
return virtualEntryPath;
|
||||
}
|
216
packages/webpack5/src/index.ts
Normal file
216
packages/webpack5/src/index.ts
Normal file
@ -0,0 +1,216 @@
|
||||
import { highlight } from 'cli-highlight';
|
||||
import { merge } from 'webpack-merge';
|
||||
import Config from 'webpack-chain';
|
||||
import webpack from 'webpack';
|
||||
|
||||
import { applyExternalConfigs } from './helpers/externalConfigs';
|
||||
import { determineProjectFlavor } from './helpers/flavor';
|
||||
import { error, info } from './helpers/log';
|
||||
import { configs } from './configuration';
|
||||
import helpers from './helpers';
|
||||
|
||||
export interface IWebpackEnv {
|
||||
[name: string]: any;
|
||||
|
||||
env?: string;
|
||||
|
||||
appPath?: string;
|
||||
appResourcesPath?: string;
|
||||
appComponents?: string[];
|
||||
|
||||
nativescriptLibPath?: string;
|
||||
|
||||
android?: boolean;
|
||||
ios?: boolean;
|
||||
// for custom platforms
|
||||
platform?: string;
|
||||
|
||||
production?: boolean;
|
||||
report?: boolean;
|
||||
hmr?: boolean;
|
||||
|
||||
// enable verbose output
|
||||
verbose?: boolean;
|
||||
|
||||
// misc
|
||||
replace?: string[] | string;
|
||||
}
|
||||
|
||||
interface IChainEntry {
|
||||
chainFn: any;
|
||||
order?: number;
|
||||
plugin?: string;
|
||||
}
|
||||
|
||||
let webpackChains: IChainEntry[] = [];
|
||||
let webpackMerges: any[] = [];
|
||||
let explicitUseConfig = false;
|
||||
let hasInitialized = false;
|
||||
let currentPlugin: string | undefined;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export let env: IWebpackEnv = {};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function setCurrentPlugin(plugin: string) {
|
||||
currentPlugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function clearCurrentPlugin() {
|
||||
currentPlugin = undefined;
|
||||
}
|
||||
|
||||
////// PUBLIC API
|
||||
/**
|
||||
* The default flavor specific configs
|
||||
*/
|
||||
export const defaultConfigs = configs;
|
||||
|
||||
/**
|
||||
* Utilities to simplify various tasks
|
||||
*/
|
||||
export const Utils = helpers;
|
||||
|
||||
/**
|
||||
* Initialize @nativescript/webpack with the webpack env.
|
||||
* Must be called first.
|
||||
*
|
||||
* @param _env The webpack env
|
||||
*/
|
||||
export function init(_env: IWebpackEnv) {
|
||||
hasInitialized = true;
|
||||
if (_env) {
|
||||
env = _env;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicitly specify the base config to use.
|
||||
* Calling this will opt-out from automatic flavor detection.
|
||||
*
|
||||
* Useful when the flavor cannot be detected due to the project structure
|
||||
* for example in a custom monorepo.
|
||||
*
|
||||
* @param config Name of the base config to use.
|
||||
*/
|
||||
export function useConfig(config: keyof typeof defaultConfigs | false) {
|
||||
explicitUseConfig = true;
|
||||
if (config) {
|
||||
webpackChains.push({
|
||||
order: -1,
|
||||
chainFn: configs[config],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new function to be called when building the internal config using webpack-chain.
|
||||
*
|
||||
* @param chainFn A function that accepts the internal chain config, and the current environment
|
||||
* @param options Optional options to control the order in which the chain function should be applied.
|
||||
*/
|
||||
export function chainWebpack(
|
||||
chainFn: (config: Config, env: IWebpackEnv) => any,
|
||||
options?: { order?: number }
|
||||
) {
|
||||
webpackChains.push({
|
||||
order: options?.order || 0,
|
||||
chainFn,
|
||||
plugin: currentPlugin,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge an object into the resolved chain config.
|
||||
*
|
||||
* @param mergeFn An object or a function that optionally returns an object (can mutate the object directly and return nothing)
|
||||
*/
|
||||
export function mergeWebpack(
|
||||
mergeFn: (
|
||||
config: Partial<webpack.Configuration>,
|
||||
env: IWebpackEnv
|
||||
) => any | Partial<webpack.Configuration>
|
||||
) {
|
||||
webpackMerges.push(mergeFn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a new instance of the internal chain config with all chain functions applied.
|
||||
*/
|
||||
export function resolveChainableConfig(): Config {
|
||||
const config = new Config();
|
||||
|
||||
if (!explicitUseConfig) {
|
||||
useConfig(determineProjectFlavor());
|
||||
}
|
||||
|
||||
// apply configs from dependencies
|
||||
// todo: allow opt-out
|
||||
applyExternalConfigs();
|
||||
|
||||
webpackChains
|
||||
.splice(0)
|
||||
.sort((a, b) => {
|
||||
return a.order - b.order;
|
||||
})
|
||||
.forEach(({ chainFn, plugin }) => {
|
||||
try {
|
||||
chainFn(config, env);
|
||||
} catch (err) {
|
||||
if (plugin) {
|
||||
// catch and print errors from plugins
|
||||
return error(`
|
||||
Unable to apply chain function from: ${plugin}.
|
||||
Error is: ${err}
|
||||
`);
|
||||
}
|
||||
|
||||
// otherwise throw - as the error is likely from the user config
|
||||
// or missing env flags (eg. missing platform)
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
if (env.verbose) {
|
||||
info('Resolved chainable config (before merges):');
|
||||
info(highlight(config.toString(), { language: 'js' }));
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a "final" configuration that has all chain functions and merges applied.
|
||||
*
|
||||
* @param chainableConfig Optional chain config to use.
|
||||
*/
|
||||
export function resolveConfig(
|
||||
chainableConfig = resolveChainableConfig()
|
||||
): webpack.Configuration {
|
||||
if (!hasInitialized) {
|
||||
throw error('resolveConfig() must be called after init()');
|
||||
}
|
||||
|
||||
let config = chainableConfig.toConfig();
|
||||
|
||||
// this applies webpack merges
|
||||
webpackMerges.forEach((mergeFn) => {
|
||||
if (typeof mergeFn === 'function') {
|
||||
// mergeFn is a function with optional return value
|
||||
const res = mergeFn(config, env);
|
||||
if (res) config = merge(config, res);
|
||||
} else if (mergeFn) {
|
||||
// mergeFn is a literal value (object)
|
||||
config = merge(config, mergeFn);
|
||||
}
|
||||
});
|
||||
|
||||
// return a config usable by webpack
|
||||
return config;
|
||||
}
|
28
packages/webpack5/src/loaders/app-css-loader/index.ts
Normal file
28
packages/webpack5/src/loaders/app-css-loader/index.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { dedent } from 'ts-dedent';
|
||||
import { basename } from 'path';
|
||||
/**
|
||||
* This loader tries to load an `app.scss` or and `app.css` relative to the main entry
|
||||
*/
|
||||
export default function loader(content: string, map: any) {
|
||||
const { platform } = this.getOptions();
|
||||
const callback = this.async();
|
||||
const resolve = this.getResolve({
|
||||
extensions: [`.${platform}.scss`, `.${platform}.css`, '.scss', '.css'],
|
||||
});
|
||||
|
||||
resolve(this.context, './app', (err, res) => {
|
||||
if (err || !res) {
|
||||
// if we ran into an error or there's no css file found, we just return
|
||||
// original content and not append any additional imports.
|
||||
return callback(null, content, map);
|
||||
}
|
||||
|
||||
const code = dedent`
|
||||
// Added by app-css-loader
|
||||
import "./${basename(res)}";
|
||||
${content}
|
||||
`;
|
||||
|
||||
callback(null, code, map);
|
||||
});
|
||||
}
|
57
packages/webpack5/src/loaders/apply-css-loader/index.ts
Normal file
57
packages/webpack5/src/loaders/apply-css-loader/index.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import { dedent } from 'ts-dedent';
|
||||
|
||||
const cssLoaderWarning = dedent`
|
||||
The apply-css-loader requires the file to be pre-processed by either css-loader or css2json-loader.
|
||||
Make sure the appropriate loader is applied before apply-css-loader.
|
||||
`;
|
||||
|
||||
export default function loader(content, map) {
|
||||
const hasLoader = (loader: string) => {
|
||||
return this.loaders
|
||||
?.slice(this.loaderIndex)
|
||||
.some(({ path }) => path.includes(loader));
|
||||
};
|
||||
// add a tag to the applied css
|
||||
const tag = JSON.stringify(this.resourcePath);
|
||||
const tagCode =
|
||||
this.mode === 'development' ? `, ${JSON.stringify(this.resourcePath)}` : '';
|
||||
|
||||
const hmrCode = this.hot
|
||||
? dedent`
|
||||
if(module.hot) {
|
||||
module.hot.accept()
|
||||
module.hot.dispose(() => {
|
||||
const { removeTaggedAdditionalCSS } = require("@nativescript/core/ui/styling/style-scope");
|
||||
removeTaggedAdditionalCSS(${tag})
|
||||
})
|
||||
}
|
||||
`
|
||||
: ``;
|
||||
|
||||
if (hasLoader('css2json-loader')) {
|
||||
content = dedent`
|
||||
${content}
|
||||
const { addTaggedAdditionalCSS } = require("@nativescript/core/ui/styling/style-scope");
|
||||
addTaggedAdditionalCSS(___CSS2JSON_LOADER_EXPORT___${tagCode})
|
||||
${hmrCode}
|
||||
`;
|
||||
} else if (hasLoader('css-loader')) {
|
||||
content = dedent`
|
||||
${content}
|
||||
const { addTaggedAdditionalCSS } = require("@nativescript/core/ui/styling/style-scope");
|
||||
if (___CSS_LOADER_EXPORT___ && typeof ___CSS_LOADER_EXPORT___.forEach === "function") {
|
||||
___CSS_LOADER_EXPORT___.forEach(cssExport => {
|
||||
if (cssExport.length > 1 && cssExport[1]) {
|
||||
// applying the second item of the export as it contains the css contents
|
||||
addTaggedAdditionalCSS(cssExport[1]${tagCode});
|
||||
}
|
||||
});
|
||||
}
|
||||
${hmrCode}
|
||||
`;
|
||||
} else {
|
||||
this.emitWarning(new Error(cssLoaderWarning));
|
||||
}
|
||||
|
||||
this.callback(null, content, null);
|
||||
}
|
81
packages/webpack5/src/loaders/css2json-loader/index.ts
Normal file
81
packages/webpack5/src/loaders/css2json-loader/index.ts
Normal file
@ -0,0 +1,81 @@
|
||||
import { parse, Import, Stylesheet } from 'css';
|
||||
import { urlToRequest } from 'loader-utils';
|
||||
import { dedent } from 'ts-dedent';
|
||||
|
||||
const betweenQuotesPattern = /('|")(.*?)\1/;
|
||||
const unpackUrlPattern = /url\(([^\)]+)\)/;
|
||||
const inlineLoader = '!css2json-loader?useForImports!';
|
||||
|
||||
export default function loader(content: string, map: any) {
|
||||
const options = this.getOptions() || {};
|
||||
const inline = !!options.useForImports;
|
||||
const requirePrefix = inline ? inlineLoader : '';
|
||||
|
||||
const ast = parse(content);
|
||||
|
||||
// todo: revise if this is necessary
|
||||
// todo: perhaps use postCSS and just build imports into a single file?
|
||||
let dependencies = [];
|
||||
getAndRemoveImportRules(ast)
|
||||
.map(extractUrlFromRule)
|
||||
.map(createRequireUri)
|
||||
.forEach(({ uri, requireURI }) => {
|
||||
dependencies.push(`require("${requirePrefix}${requireURI}")`);
|
||||
});
|
||||
|
||||
const str = JSON.stringify(ast, (k, v) => (k === 'position' ? undefined : v));
|
||||
|
||||
// map.mappings = map.mappings.replace(/;{2,}/, '')
|
||||
|
||||
const code = dedent`
|
||||
/* CSS2JSON */
|
||||
${dependencies.join('\n')}
|
||||
const ___CSS2JSON_LOADER_EXPORT___ = ${str}
|
||||
export default ___CSS2JSON_LOADER_EXPORT___
|
||||
`;
|
||||
this.callback(
|
||||
null,
|
||||
code, //`${dependencies.join('\n')}module.exports = ${str};`,
|
||||
map
|
||||
);
|
||||
}
|
||||
|
||||
function getImportRules(ast: Stylesheet): Import[] {
|
||||
if (!ast || (<any>ast).type !== 'stylesheet' || !ast.stylesheet) {
|
||||
return [];
|
||||
}
|
||||
return <Import[]>(
|
||||
ast.stylesheet.rules.filter(
|
||||
(rule) => rule.type === 'import' && (<any>rule).import
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function getAndRemoveImportRules(ast: Stylesheet): Import[] {
|
||||
const imports = getImportRules(ast);
|
||||
ast.stylesheet.rules = ast.stylesheet.rules.filter(
|
||||
(rule) => rule.type !== 'import'
|
||||
);
|
||||
|
||||
return imports;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the url from import rule (ex. `url("./platform.css")`)
|
||||
*/
|
||||
function extractUrlFromRule(importRule: Import): string {
|
||||
const urlValue = importRule.import;
|
||||
|
||||
const unpackedUrlMatch = urlValue.match(unpackUrlPattern);
|
||||
const unpackedValue = unpackedUrlMatch ? unpackedUrlMatch[1] : urlValue;
|
||||
|
||||
const quotesMatch = unpackedValue.match(betweenQuotesPattern);
|
||||
return quotesMatch ? quotesMatch[2] : unpackedValue;
|
||||
}
|
||||
|
||||
function createRequireUri(uri): { uri: string; requireURI: string } {
|
||||
return {
|
||||
uri: uri,
|
||||
requireURI: urlToRequest(uri),
|
||||
};
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
// @ts-nocheck
|
||||
// This is a runtime module - included by nativescript-hot-loader
|
||||
// this file should not include external dependencies
|
||||
// ---
|
||||
|
||||
if (module.hot) {
|
||||
let hash = __webpack_require__.h();
|
||||
|
||||
const logVerbose = (title: string, ...info: any) => {
|
||||
if (__NS_ENV_VERBOSE__) {
|
||||
console.log(`[HMR][Verbose] ${title}`);
|
||||
|
||||
if (info?.length) {
|
||||
console.log(...info);
|
||||
console.log('---');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const setStatus = (
|
||||
hash: string,
|
||||
status: 'success' | 'failure',
|
||||
message?: string,
|
||||
...info: any
|
||||
): boolean => {
|
||||
// format is important - CLI expects this exact format
|
||||
console.log(`[HMR][${hash}] ${status} | ${message}`);
|
||||
if (info?.length) {
|
||||
logVerbose('Additional Info', info);
|
||||
}
|
||||
|
||||
// return true if operation was successful
|
||||
return status === 'success';
|
||||
};
|
||||
|
||||
const applyOptions = {
|
||||
ignoreUnaccepted: false,
|
||||
ignoreDeclined: false,
|
||||
ignoreErrored: false,
|
||||
onDeclined(info) {
|
||||
setStatus(hash, 'failure', 'A module has been declined.', info);
|
||||
},
|
||||
onUnaccepted(info) {
|
||||
setStatus(hash, 'failure', 'A module has not been accepted.', info);
|
||||
},
|
||||
onAccepted(info) {
|
||||
// console.log('accepted', info)
|
||||
logVerbose('Module Accepted', info);
|
||||
},
|
||||
onDisposed(info) {
|
||||
// console.log('disposed', info)
|
||||
logVerbose('Module Disposed', info);
|
||||
},
|
||||
onErrored(info) {
|
||||
setStatus(hash, 'failure', 'A module has errored.', info);
|
||||
},
|
||||
};
|
||||
|
||||
const checkAndApply = async () => {
|
||||
hash = __webpack_require__.h();
|
||||
const modules = await module.hot.check().catch((error) => {
|
||||
return setStatus(
|
||||
hash,
|
||||
'failure',
|
||||
'Failed to check.',
|
||||
error.message || error.stack
|
||||
);
|
||||
});
|
||||
|
||||
if (!modules) {
|
||||
logVerbose('No modules to apply.');
|
||||
return false;
|
||||
}
|
||||
|
||||
const appliedModules = await module.hot
|
||||
.apply(applyOptions)
|
||||
.catch((error) => {
|
||||
return setStatus(
|
||||
hash,
|
||||
'failure',
|
||||
'Failed to apply.',
|
||||
error.message || error.stack
|
||||
);
|
||||
});
|
||||
|
||||
if (!appliedModules) {
|
||||
logVerbose('No modules applied.');
|
||||
return false;
|
||||
}
|
||||
|
||||
return setStatus(hash, 'success', 'Successfully applied update.');
|
||||
};
|
||||
|
||||
const hasUpdate = () => {
|
||||
try {
|
||||
__non_webpack_require__(`~/bundle.${__webpack_hash__}.hot-update.json`);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const originalOnLiveSync = global.__onLiveSync;
|
||||
global.__onLiveSync = async function () {
|
||||
logVerbose('LiveSync');
|
||||
|
||||
if (!hasUpdate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
await checkAndApply();
|
||||
originalOnLiveSync();
|
||||
};
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
import { relative, resolve } from 'path';
|
||||
import dedent from 'ts-dedent';
|
||||
import fs from 'fs';
|
||||
|
||||
// note: this will bail even if module.hot appears in a comment
|
||||
const MODULE_HOT_RE = /module\.hot/;
|
||||
|
||||
export default function loader(content: string, map: any) {
|
||||
if (MODULE_HOT_RE.test(content)) {
|
||||
// Code already handles HMR - we don't need to do anything
|
||||
return this.callback(null, content, map);
|
||||
}
|
||||
const opts = this.getOptions();
|
||||
|
||||
// used to inject the HMR runtime into the entry file
|
||||
if (opts.injectHMRRuntime) {
|
||||
const hmrRuntimePath = resolve(__dirname, './hmr.runtime.js');
|
||||
const hmrRuntime = fs
|
||||
.readFileSync(hmrRuntimePath)
|
||||
.toString()
|
||||
.split('// ---')[1]
|
||||
.replace('//# sourceMappingURL=hmr.runtime.js.map', '');
|
||||
|
||||
return this.callback(null, `${content}\n${hmrRuntime}`, map);
|
||||
}
|
||||
|
||||
const relativePath = relative(
|
||||
opts.appPath ?? this.rootContext,
|
||||
this.resourcePath
|
||||
).replace(/\\/g, '/');
|
||||
|
||||
const hmrCode = this.hot
|
||||
? dedent`
|
||||
/* NATIVESCRIPT-HOT-LOADER */
|
||||
if(module.hot && global._isModuleLoadedForUI && global._isModuleLoadedForUI("./${relativePath}")) {
|
||||
module.hot.accept()
|
||||
}
|
||||
`
|
||||
: ``;
|
||||
|
||||
const source = `${content}\n${hmrCode}`;
|
||||
|
||||
this.callback(null, source, map);
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
const WorkerDependency = require('webpack/lib/dependencies/WorkerDependency');
|
||||
const RuntimeGlobals = require('webpack/lib/RuntimeGlobals');
|
||||
|
||||
/**
|
||||
* Patch WorkerDependency to change:
|
||||
*
|
||||
* new Worker(new URL(workerPath, baseUrl))
|
||||
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
* to.
|
||||
*
|
||||
* new Worker('~/' + workerPath)
|
||||
*
|
||||
* Note: we are changing source **outside** of the dependency range, and this may
|
||||
* break when the dependency range changes, for example if this PR is merged:
|
||||
* - https://github.com/webpack/webpack/pull/12750
|
||||
*/
|
||||
WorkerDependency.Template.prototype.apply = function apply(
|
||||
dependency,
|
||||
source,
|
||||
templateContext
|
||||
) {
|
||||
const { chunkGraph, moduleGraph, runtimeRequirements } = templateContext;
|
||||
const dep = /** @type {WorkerDependency} */ dependency;
|
||||
const block = /** @type {AsyncDependenciesBlock} */ moduleGraph.getParentBlock(
|
||||
dependency
|
||||
);
|
||||
const entrypoint = /** @type {Entrypoint} */ chunkGraph.getBlockChunkGroup(
|
||||
block
|
||||
);
|
||||
const chunk = entrypoint.getEntrypointChunk();
|
||||
|
||||
// runtimeRequirements.add(RuntimeGlobals.publicPath);
|
||||
// runtimeRequirements.add(RuntimeGlobals.baseURI);
|
||||
runtimeRequirements.add(RuntimeGlobals.getChunkScriptFilename);
|
||||
|
||||
/**
|
||||
* new URL(
|
||||
* ^^^^^^^^ = 8 characters, we subtract it from the dep.range[0]
|
||||
*/
|
||||
source.replace(
|
||||
dep.range[0] - 8,
|
||||
dep.range[1],
|
||||
`/* worker import */ /* patched by nativescript-worker-loader */ '~/' + ${
|
||||
RuntimeGlobals.getChunkScriptFilename
|
||||
}(${JSON.stringify(chunk.id)})`
|
||||
);
|
||||
};
|
||||
|
||||
const NEW_WORKER_WITH_STRING_RE = /new\s+Worker\((['"`].+['"`])\)/;
|
||||
|
||||
/**
|
||||
* Replaces
|
||||
* new Worker('./somePath')
|
||||
* with
|
||||
* new Worker(new URL('./somePath', import.meta.url))
|
||||
*/
|
||||
export default function loader(content: string, map: any) {
|
||||
const source = content.replace(
|
||||
NEW_WORKER_WITH_STRING_RE,
|
||||
'new Worker(new URL($1, import.meta.url))'
|
||||
);
|
||||
this.callback(null, source, map);
|
||||
}
|
238
packages/webpack5/src/loaders/xml-namespace-loader/index.ts
Normal file
238
packages/webpack5/src/loaders/xml-namespace-loader/index.ts
Normal file
@ -0,0 +1,238 @@
|
||||
import { parse, join } from 'path';
|
||||
import { promisify } from 'util';
|
||||
import dedent from 'ts-dedent';
|
||||
import { parser } from 'sax';
|
||||
|
||||
const noop = () => {};
|
||||
|
||||
const DEBUG = false;
|
||||
|
||||
interface NamespaceEntry {
|
||||
name: string;
|
||||
path: string;
|
||||
}
|
||||
|
||||
interface ParseResult {
|
||||
code: string;
|
||||
}
|
||||
|
||||
export default function loader(content: string, map: any) {
|
||||
const callback = this.async();
|
||||
|
||||
// parse content and dependencies async
|
||||
parseXML
|
||||
.bind(this)(content)
|
||||
.then((res) => {
|
||||
DEBUG && console.log({ res });
|
||||
callback(null, res.code, map);
|
||||
})
|
||||
.catch((err) => {
|
||||
DEBUG && console.log({ err });
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
|
||||
async function parseXML(content: string): Promise<ParseResult> {
|
||||
// wrap this.resolve into a promise
|
||||
const resolveAsync = promisify(this.resolve);
|
||||
const promises: Promise<any>[] = [];
|
||||
const namespaces: NamespaceEntry[] = [];
|
||||
const distinctNamespaces = new Map<string, string>();
|
||||
const moduleRegisters: string[] = [];
|
||||
const { ignore } = this.query;
|
||||
const errors = [];
|
||||
|
||||
const saxParser = parser(true, { xmlns: true });
|
||||
|
||||
// // Register ios and android prefixes as namespaces to avoid "unbound xml namespace" errors
|
||||
(saxParser as any).ns['ios'] = 'http://schemas.nativescript.org/tns.xsd';
|
||||
(saxParser as any).ns['android'] = 'http://schemas.nativescript.org/tns.xsd';
|
||||
(saxParser as any).ns['desktop'] = 'http://schemas.nativescript.org/tns.xsd';
|
||||
(saxParser as any).ns['web'] = 'http://schemas.nativescript.org/tns.xsd';
|
||||
|
||||
const handleOpenTag = async (namespace: string, elementName: string) => {
|
||||
if (!namespace) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (namespace.startsWith('http')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const moduleName = `${namespace}/${elementName}`;
|
||||
|
||||
if (namespaces.some((n) => n.name === moduleName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ignore && moduleName.match(ignore)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const localNamespacePath = join(this.rootContext, namespace);
|
||||
const localModulePath = join(localNamespacePath, elementName);
|
||||
|
||||
const resolvePaths = [
|
||||
localNamespacePath,
|
||||
localModulePath,
|
||||
`${localModulePath}.xml`,
|
||||
moduleName,
|
||||
namespace,
|
||||
];
|
||||
DEBUG && console.log({ resolvePaths });
|
||||
let resolvedPath;
|
||||
|
||||
for (const p of resolvePaths) {
|
||||
resolvedPath = await resolveAsync(this.context, p).catch(noop);
|
||||
|
||||
// break on first match
|
||||
if (resolvedPath) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG && console.log({ resolvedPath });
|
||||
|
||||
// bail if we haven't resolved a path
|
||||
if (!resolvedPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { dir, name } = parse(resolvedPath);
|
||||
|
||||
// register resolved path + short name
|
||||
namespaces.push({ name: namespace, path: resolvedPath });
|
||||
namespaces.push({ name: moduleName, path: resolvedPath });
|
||||
this.addDependency(resolvedPath);
|
||||
|
||||
const noExtFilename = join(dir, name);
|
||||
|
||||
DEBUG &&
|
||||
console.log({
|
||||
noExtFilename,
|
||||
});
|
||||
|
||||
// finally try resolving an XML file
|
||||
await resolveAsync(this.context, `${noExtFilename}.xml`)
|
||||
.then((xml) => {
|
||||
this.addDependency(xml);
|
||||
namespaces.push({ name: `${moduleName}.xml`, path: xml });
|
||||
})
|
||||
.catch(() => {
|
||||
// if there is no XML file, fall back to namespace as the path
|
||||
// will become require(<namespace>)
|
||||
namespaces.push({ name: namespace, path: namespace });
|
||||
namespaces.push({ name: moduleName, path: namespace });
|
||||
});
|
||||
|
||||
// look for css files with the same name
|
||||
await resolveAsync(this.context, `${noExtFilename}.css`)
|
||||
.then((css) => {
|
||||
this.addDependency(css);
|
||||
namespaces.push({ name: `${moduleName}.css`, path: css });
|
||||
})
|
||||
.catch(noop);
|
||||
};
|
||||
|
||||
saxParser.onopentag = (node) => {
|
||||
if ('uri' in node) {
|
||||
promises.push(handleOpenTag(node.uri, node.local));
|
||||
}
|
||||
};
|
||||
saxParser.onerror = (error) => {
|
||||
saxParser.error = null;
|
||||
|
||||
// Do only warning about invalid character "&"" for back-compatibility
|
||||
// as it is common to use it in a binding expression
|
||||
if (
|
||||
error.message.includes('Invalid character') &&
|
||||
error.message.includes('Char: &')
|
||||
) {
|
||||
return this.emitWarning(error);
|
||||
}
|
||||
errors.push(error);
|
||||
};
|
||||
|
||||
saxParser.write(content).close();
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
DEBUG && console.log({ namespaces });
|
||||
|
||||
namespaces.forEach(({ name, path }) => {
|
||||
distinctNamespaces.set(name, path.replace(/\\/g, '/'));
|
||||
});
|
||||
|
||||
distinctNamespaces.forEach((path, name) => {
|
||||
moduleRegisters.push(dedent`
|
||||
global.registerModule(
|
||||
'${name}',
|
||||
() => require("${path}")
|
||||
)
|
||||
`);
|
||||
});
|
||||
|
||||
// escape special whitespace characters
|
||||
// see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Issue_with_plain_JSON.stringify_for_use_as_JavaScript
|
||||
const xml = JSON.stringify(content)
|
||||
.replace(/\u2028/g, '\\u2028')
|
||||
.replace(/\u2029/g, '\\u2029');
|
||||
|
||||
const hmrCode = this.hot
|
||||
? dedent`
|
||||
if(module.hot) {
|
||||
module.hot.accept()
|
||||
// module.hot.dispose(() => {})
|
||||
}
|
||||
`
|
||||
: ``;
|
||||
|
||||
const code = dedent`
|
||||
${moduleRegisters.join('\n')}
|
||||
/* XML-NAMESPACE-LOADER */
|
||||
const ___XML_NAMESPACE_LOADER_EXPORT___ = ${xml}
|
||||
export default ___XML_NAMESPACE_LOADER_EXPORT___
|
||||
${hmrCode}
|
||||
`;
|
||||
|
||||
if (errors.length) {
|
||||
errors.map(this.emitError);
|
||||
|
||||
// finally throw the first one
|
||||
throw errors[0];
|
||||
}
|
||||
|
||||
return {
|
||||
code,
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
// function parseXML(xml: string) {
|
||||
// const saxParser = parser(true, { xmlns: true });
|
||||
//
|
||||
// saxParser.onopentag = (node) => {
|
||||
// if('ns' in node) {
|
||||
// const uri = node.uri
|
||||
// const tag = node.local
|
||||
//
|
||||
// DEBUG && console.log({
|
||||
// uri,
|
||||
// tag
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// saxParser.onerror = (err) => {
|
||||
// DEBUG && console.log(err)
|
||||
// }
|
||||
//
|
||||
// // Register ios and android prefixes as namespaces to avoid "unbound xml namespace" errors
|
||||
// // saxParser.ns['ios'] = 'http://schemas.nativescript.org/tns.xsd';
|
||||
// // saxParser.ns['android'] = 'http://schemas.nativescript.org/tns.xsd';
|
||||
// // saxParser.ns['desktop'] = 'http://schemas.nativescript.org/tns.xsd';
|
||||
// // saxParser.ns['web'] = 'http://schemas.nativescript.org/tns.xsd';
|
||||
// saxParser.write(xml).close()
|
||||
// }
|
11
packages/webpack5/src/platforms/android.ts
Normal file
11
packages/webpack5/src/platforms/android.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { INativeScriptPlatform } from "../helpers/platform";
|
||||
|
||||
function getDistPath() {
|
||||
return `platforms/android/app/src/main/assets/app`;
|
||||
}
|
||||
|
||||
const AndroidPlatform: INativeScriptPlatform = {
|
||||
getDistPath,
|
||||
}
|
||||
|
||||
export default AndroidPlatform;
|
20
packages/webpack5/src/platforms/ios.ts
Normal file
20
packages/webpack5/src/platforms/ios.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { basename } from "path";
|
||||
|
||||
import { INativeScriptPlatform } from "../helpers/platform";
|
||||
import { getProjectRootPath } from "../helpers/project";
|
||||
|
||||
function sanitizeName(appName: string): string {
|
||||
return appName.split("").filter((c) =>
|
||||
/[a-zA-Z0-9]/.test(c)
|
||||
).join("");
|
||||
}
|
||||
function getDistPath() {
|
||||
const appName = sanitizeName(basename(getProjectRootPath()));
|
||||
return `platforms/ios/${appName}/app`;
|
||||
}
|
||||
|
||||
const iOSPlatform: INativeScriptPlatform = {
|
||||
getDistPath,
|
||||
}
|
||||
|
||||
export default iOSPlatform;
|
161
packages/webpack5/src/plugins/PlatformSuffixPlugin.ts
Normal file
161
packages/webpack5/src/plugins/PlatformSuffixPlugin.ts
Normal file
@ -0,0 +1,161 @@
|
||||
import { extname, resolve } from 'path';
|
||||
import { existsSync } from 'fs';
|
||||
|
||||
const id = 'PlatformSuffixPlugin';
|
||||
|
||||
interface PlatformSuffixPluginOptions {
|
||||
platform: string;
|
||||
// extensions: string[] | (() => string[])
|
||||
}
|
||||
|
||||
/**
|
||||
* The platform suffix plugin will try to resolve files with a platform specifier (suffix)
|
||||
* falling back to the non-platform-specific version.
|
||||
*
|
||||
* For example:
|
||||
* import something from './something.js'
|
||||
*
|
||||
* will first look for './something.<platform>.js'
|
||||
* and if not found look for './something.js'
|
||||
*
|
||||
*/
|
||||
export class PlatformSuffixPlugin {
|
||||
private readonly platform: string;
|
||||
// private readonly extensions: string[]
|
||||
|
||||
constructor(options: PlatformSuffixPluginOptions) {
|
||||
this.platform = options.platform;
|
||||
|
||||
// if (typeof options.extensions === "function") {
|
||||
// this.extensions = options.extensions()
|
||||
// } else {
|
||||
// this.extensions = options.extensions
|
||||
// }
|
||||
}
|
||||
|
||||
apply(compiler: any) {
|
||||
const platformRE = new RegExp(`\.${this.platform}\.`);
|
||||
|
||||
// require.context
|
||||
compiler.hooks.contextModuleFactory.tap(id, (cmf) => {
|
||||
// @ts-ignore
|
||||
cmf.hooks.alternativeRequests.tap(id, (modules, options) => {
|
||||
const additionalModules = [];
|
||||
// we are looking for modules that are platform specific (something.<platform>.ext)
|
||||
// and we are duplicating them without the platform suffix
|
||||
// this allows using require.context with non-existent platformless filenames
|
||||
// but mapped to the platform specific variant (done in the resolver hook below)
|
||||
for (const module of modules) {
|
||||
if (platformRE.test(module.request)) {
|
||||
additionalModules.push({
|
||||
...module,
|
||||
request: module.request.replace(platformRE, '.'),
|
||||
});
|
||||
}
|
||||
}
|
||||
modules.push(...additionalModules);
|
||||
});
|
||||
});
|
||||
|
||||
compiler.resolverFactory.hooks.resolver
|
||||
.for('normal')
|
||||
.tap(id, (resolver) => {
|
||||
// Object.keys(resolver.hooks).forEach(hook => {
|
||||
// resolver.hooks[hook].tap(id, (request, resolveContext) => {
|
||||
// if(
|
||||
// request?.path?.includes('foo.xml') ||
|
||||
// request?.request?.includes('foo.xml')
|
||||
// ) {
|
||||
// console.log(
|
||||
// `>>> ${hook}: ${request.path}`,
|
||||
// // request
|
||||
// )
|
||||
// }
|
||||
// // callback();
|
||||
// });
|
||||
// })
|
||||
|
||||
resolver.hooks.normalResolve.tapAsync(
|
||||
id,
|
||||
(request_, resolveContext, callback) => {
|
||||
const { path, request } = request_;
|
||||
const ext = request && extname(request);
|
||||
const platformExt = ext ? `.${this.platform}${ext}` : '';
|
||||
|
||||
if (path && request && ext && !request.includes(platformExt)) {
|
||||
const platformRequest = request.replace(ext, platformExt);
|
||||
const extPath = resolve(path, platformRequest);
|
||||
|
||||
// console.log({
|
||||
// path,
|
||||
// request,
|
||||
// ext,
|
||||
// extPath
|
||||
// })
|
||||
|
||||
// if a file with the same + a platform suffix exists
|
||||
// we want to resolve that file instead
|
||||
if (existsSync(extPath)) {
|
||||
const message = `resolving "${request}" to "${platformRequest}"`;
|
||||
const hook = resolver.ensureHook('normalResolve');
|
||||
console.log(message);
|
||||
|
||||
// here we are creating a new resolve object and replacing the path
|
||||
// with the .<platform>.<ext> suffix
|
||||
const obj = {
|
||||
...request_,
|
||||
path: resolver.join(path, platformRequest),
|
||||
relativePath:
|
||||
request_.relativePath &&
|
||||
resolver.join(request_.relativePath, platformRequest),
|
||||
request: undefined,
|
||||
};
|
||||
|
||||
// we call to the actual resolver to do the resolving of this new file
|
||||
return resolver.doResolve(
|
||||
hook,
|
||||
obj,
|
||||
message,
|
||||
resolveContext,
|
||||
callback
|
||||
);
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
);
|
||||
// resolver.hooks.rawFile.tap(id, (request, resolveContext, callback) => {
|
||||
// if(request.path && !/\.ios\..+$/.test(request.path)) {
|
||||
// const { ext } = parse(request.path)
|
||||
// const platformExtPath = request.path.replace(ext, `.${this.platform}${ext}`)
|
||||
// // console.log({
|
||||
// // p1: request.path,
|
||||
// // p2: platformExtPath
|
||||
// // })
|
||||
// if(existsSync(platformExtPath)) {
|
||||
// // request.path = platformExtPath
|
||||
// // console.log('-'.repeat(100))
|
||||
// // console.log(request)
|
||||
// const obj = {
|
||||
// ...request,
|
||||
// path: platformExtPath,
|
||||
// fullySpecified: false
|
||||
// }
|
||||
// return resolver.doResolve(
|
||||
// 'raw-file',
|
||||
// obj,
|
||||
// `resolved ${request.path} to platform specific file: ${platformExtPath}`,
|
||||
// resolveContext,
|
||||
// (err, result) => {
|
||||
// if(err) return callback(err);
|
||||
// if(result) return callback(null, result);
|
||||
// return callback();
|
||||
// }
|
||||
// )
|
||||
// // return request
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
});
|
||||
}
|
||||
}
|
96
packages/webpack5/src/plugins/WatchStatePlugin.ts
Normal file
96
packages/webpack5/src/plugins/WatchStatePlugin.ts
Normal file
@ -0,0 +1,96 @@
|
||||
import { env } from '../';
|
||||
|
||||
const id = 'WatchStatePlugin';
|
||||
const version = 1;
|
||||
|
||||
export enum messages {
|
||||
compilationComplete = 'Webpack compilation complete.',
|
||||
startWatching = 'Webpack compilation complete. Watching for file changes.',
|
||||
changeDetected = 'File change detected. Starting incremental webpack compilation...',
|
||||
}
|
||||
|
||||
/**
|
||||
* This little plugin will report the webpack state through the console
|
||||
* and send status updates through IPC to the {N} CLI.
|
||||
*/
|
||||
export class WatchStatePlugin {
|
||||
apply(compiler: any) {
|
||||
let isWatchMode = false;
|
||||
let prevAssets = [];
|
||||
|
||||
compiler.hooks.watchRun.tapAsync(id, function (compiler, callback) {
|
||||
callback();
|
||||
|
||||
if (isWatchMode) {
|
||||
console.log(messages.changeDetected);
|
||||
|
||||
if (env.verbose) {
|
||||
if (compiler.modifiedFiles) {
|
||||
Array.from(compiler.modifiedFiles).forEach((file) => {
|
||||
console.log(`[${id}][WatchTriggers] MODIFIED: ${file}`);
|
||||
});
|
||||
}
|
||||
|
||||
if (compiler.removedFiles) {
|
||||
Array.from(compiler.removedFiles).forEach((file) => {
|
||||
console.log(`[${id}][WatchTriggers] REMOVED: ${file}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
isWatchMode = true;
|
||||
});
|
||||
|
||||
compiler.hooks.afterEmit.tapAsync(id, function (compilation, callback) {
|
||||
callback();
|
||||
|
||||
console.log(
|
||||
isWatchMode ? messages.startWatching : messages.compilationComplete
|
||||
);
|
||||
|
||||
// logic taken from CleanWebpackPlugin
|
||||
const assets =
|
||||
compilation.getStats().toJson(
|
||||
{
|
||||
assets: true,
|
||||
},
|
||||
true
|
||||
).assets || [];
|
||||
const assetList = assets.map((asset) => asset.name);
|
||||
|
||||
const emittedAssets = Array.from(compilation.emittedAssets);
|
||||
const staleAssets = prevAssets.filter((asset) => {
|
||||
return assetList.includes(asset) === false;
|
||||
});
|
||||
|
||||
// store assets for next compilation
|
||||
prevAssets = assetList.sort();
|
||||
|
||||
notify({
|
||||
type: 'compilation',
|
||||
version,
|
||||
hash: compilation.hash,
|
||||
|
||||
data: {
|
||||
emittedAssets,
|
||||
staleAssets,
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function notify(message: any) {
|
||||
env.verbose && console.log(`[${id}] Notify: `, message);
|
||||
if (!process.send) {
|
||||
return;
|
||||
}
|
||||
|
||||
process.send(message, (error) => {
|
||||
if (error) {
|
||||
console.error(`[${id}] Process Send Error: `, error);
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
12
packages/webpack5/src/stubs/default.config.stub.js
Normal file
12
packages/webpack5/src/stubs/default.config.stub.js
Normal file
@ -0,0 +1,12 @@
|
||||
const webpack = require("@nativescript/webpack");
|
||||
|
||||
module.exports = (env) => {
|
||||
webpack.init(env);
|
||||
|
||||
// Learn how to customize:
|
||||
// https://docs.nativescript.org/webpack
|
||||
|
||||
return webpack.resolveConfig();
|
||||
};
|
||||
|
||||
|
1
packages/webpack5/src/transformers/AngularHMR/index.ts
Normal file
1
packages/webpack5/src/transformers/AngularHMR/index.ts
Normal file
@ -0,0 +1 @@
|
||||
// todo
|
51
packages/webpack5/src/transformers/NativeClass/index.ts
Normal file
51
packages/webpack5/src/transformers/NativeClass/index.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import ts from 'typescript';
|
||||
|
||||
/**
|
||||
* A TypeScript transform that compiles classes marked with @NativeClass as es5 & commonjs
|
||||
*
|
||||
* @param ctx
|
||||
*/
|
||||
export default function (ctx: ts.TransformationContext) {
|
||||
function isNativeClassExtension(node: ts.ClassDeclaration) {
|
||||
return (
|
||||
node.decorators &&
|
||||
node.decorators.filter((d) => {
|
||||
const fullText = d.getFullText().trim();
|
||||
return fullText.indexOf('@NativeClass') > -1;
|
||||
}).length > 0
|
||||
);
|
||||
}
|
||||
function visitNode(node: ts.Node): ts.Node {
|
||||
if (ts.isClassDeclaration(node) && isNativeClassExtension(node)) {
|
||||
return createHelper(node);
|
||||
}
|
||||
return ts.visitEachChild(node, visitNode, ctx);
|
||||
}
|
||||
|
||||
function createHelper(node: ts.Node) {
|
||||
// we remove the decorator for now!
|
||||
return ts.createIdentifier(
|
||||
ts
|
||||
.transpileModule(
|
||||
node.getText().replace(/@NativeClass(\((.|\n)*?\))?/gm, ''),
|
||||
{
|
||||
compilerOptions: {
|
||||
noEmitHelpers: true,
|
||||
module: ts.ModuleKind.CommonJS,
|
||||
target: ts.ScriptTarget.ES5,
|
||||
},
|
||||
}
|
||||
)
|
||||
.outputText.replace(
|
||||
/(Object\.defineProperty\(.*?{.*?)(enumerable:\s*false)(.*?}\))/gs,
|
||||
'$1enumerable: true$3'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (source: ts.SourceFile) =>
|
||||
ts.updateSourceFileNode(
|
||||
source,
|
||||
ts.visitNodes(source.statements, visitNode)
|
||||
);
|
||||
}
|
7
packages/webpack5/tsconfig.build.json
Normal file
7
packages/webpack5/tsconfig.build.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
25
packages/webpack5/tsconfig.json
Normal file
25
packages/webpack5/tsconfig.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"rootDir": ".",
|
||||
"baseUrl": ".",
|
||||
"target": "es2017",
|
||||
"module": "commonjs",
|
||||
"outDir": "./dist",
|
||||
"declaration": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"lib": ["es2017"],
|
||||
"sourceMap": true,
|
||||
"skipLibCheck": true,
|
||||
"skipDefaultLibCheck": true,
|
||||
"diagnostics": true,
|
||||
"paths": {
|
||||
"@nativescript/webpack": ["src"]
|
||||
},
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"stripInternal": true
|
||||
},
|
||||
"include": ["src", "scripts", "__tests__"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
@ -115,6 +115,13 @@ module.exports = {
|
||||
test: {
|
||||
script: 'nx run webpack:test',
|
||||
description: '@nativescript/webpack: Unit tests'
|
||||
},
|
||||
},
|
||||
// @nativescript/webpack (5)
|
||||
webpack5: {
|
||||
build: {
|
||||
script: 'nx run webpack5:build',
|
||||
description: '@nativescript/webpack(5): Build for npm'
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -253,6 +253,31 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"webpack5": {
|
||||
"root": "packages/webpack5",
|
||||
"sourceRoot": "packages/webpack5",
|
||||
"projectType": "library",
|
||||
"schematics": {},
|
||||
"architect": {
|
||||
"lint": {
|
||||
"builder": "@nrwl/linter:eslint",
|
||||
"options": {
|
||||
"lintFilePatterns": []
|
||||
}
|
||||
},
|
||||
"build": {
|
||||
"builder": "@nrwl/workspace:run-commands",
|
||||
"outputs": ["dist/packages"],
|
||||
"options": {
|
||||
"commands": [
|
||||
"npm run build"
|
||||
],
|
||||
"cwd": "packages/webpack5",
|
||||
"parallel": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
|
Reference in New Issue
Block a user