mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-18 05:18:39 +08:00
feat: external config loading
+refactor many pieces
This commit is contained in:

committed by
Nathan Walker

parent
04d989c2e6
commit
575130c712
@ -97,9 +97,9 @@ exports[`react configuration > android > adds ReactRefreshWebpackPlugin when HMR
|
||||
{
|
||||
loader: 'apply-css-loader'
|
||||
},
|
||||
/* config.module.rule('css').use('css-loader') */
|
||||
/* config.module.rule('css').use('css2json-loader') */
|
||||
{
|
||||
loader: 'css-loader'
|
||||
loader: 'css2json-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -107,6 +107,10 @@ exports[`react configuration > android > adds ReactRefreshWebpackPlugin when HMR
|
||||
{
|
||||
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'
|
||||
@ -120,6 +124,16 @@ exports[`react configuration > android > adds ReactRefreshWebpackPlugin when HMR
|
||||
]
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
defaultVendor: {
|
||||
test: /[\\\\\\\\/]node_modules[\\\\\\\\/]/,
|
||||
priority: -10,
|
||||
name: 'vendor',
|
||||
chunks: 'all'
|
||||
}
|
||||
}
|
||||
},
|
||||
minimizer: [
|
||||
/* config.optimization.minimizer('TerserPlugin') */
|
||||
new TerserPlugin(
|
||||
@ -142,22 +156,27 @@ exports[`react configuration > android > adds ReactRefreshWebpackPlugin when HMR
|
||||
cleanOnceBeforeBuildPatterns: [
|
||||
'__jest__/platforms/android/app/src/main/assets/app/**/*'
|
||||
],
|
||||
verbose: true
|
||||
verbose: false
|
||||
}
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
'global.NS_WEBPACK': true,
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__CSS_PARSER__: '\\"css-tree\\"',
|
||||
__ANDROID__: true,
|
||||
__IOS__: false,
|
||||
'global.isAndroid': true,
|
||||
'global.isIOS': false,
|
||||
process: 'global.process',
|
||||
profile: '() => {}',
|
||||
__DEV__: 'true',
|
||||
__TEST__: 'false',
|
||||
'process.env.NODE_ENV': '\\"development\\"'
|
||||
}
|
||||
),
|
||||
/* config.plugin('BundleAnalyzerPlugin') */
|
||||
new BundleAnalyzerPlugin(),
|
||||
/* config.plugin('WatchStateLoggerPlugin') */
|
||||
new WatchStateLoggerPlugin(),
|
||||
/* config.plugin('ReactRefreshWebpackPlugin') */
|
||||
@ -273,9 +292,9 @@ exports[`react configuration > android > base config 1`] = `
|
||||
{
|
||||
loader: 'apply-css-loader'
|
||||
},
|
||||
/* config.module.rule('css').use('css-loader') */
|
||||
/* config.module.rule('css').use('css2json-loader') */
|
||||
{
|
||||
loader: 'css-loader'
|
||||
loader: 'css2json-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -283,6 +302,10 @@ exports[`react configuration > android > base config 1`] = `
|
||||
{
|
||||
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'
|
||||
@ -296,6 +319,16 @@ exports[`react configuration > android > base config 1`] = `
|
||||
]
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
defaultVendor: {
|
||||
test: /[\\\\\\\\/]node_modules[\\\\\\\\/]/,
|
||||
priority: -10,
|
||||
name: 'vendor',
|
||||
chunks: 'all'
|
||||
}
|
||||
}
|
||||
},
|
||||
minimizer: [
|
||||
/* config.optimization.minimizer('TerserPlugin') */
|
||||
new TerserPlugin(
|
||||
@ -318,22 +351,27 @@ exports[`react configuration > android > base config 1`] = `
|
||||
cleanOnceBeforeBuildPatterns: [
|
||||
'__jest__/platforms/android/app/src/main/assets/app/**/*'
|
||||
],
|
||||
verbose: true
|
||||
verbose: false
|
||||
}
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
'global.NS_WEBPACK': true,
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__CSS_PARSER__: '\\"css-tree\\"',
|
||||
__ANDROID__: true,
|
||||
__IOS__: false,
|
||||
'global.isAndroid': true,
|
||||
'global.isIOS': false,
|
||||
process: 'global.process',
|
||||
profile: '() => {}',
|
||||
__DEV__: 'true',
|
||||
__TEST__: 'false',
|
||||
'process.env.NODE_ENV': '\\"development\\"'
|
||||
}
|
||||
),
|
||||
/* config.plugin('BundleAnalyzerPlugin') */
|
||||
new BundleAnalyzerPlugin(),
|
||||
/* config.plugin('WatchStateLoggerPlugin') */
|
||||
new WatchStateLoggerPlugin()
|
||||
],
|
||||
@ -442,9 +480,9 @@ exports[`react configuration > ios > adds ReactRefreshWebpackPlugin when HMR ena
|
||||
{
|
||||
loader: 'apply-css-loader'
|
||||
},
|
||||
/* config.module.rule('css').use('css-loader') */
|
||||
/* config.module.rule('css').use('css2json-loader') */
|
||||
{
|
||||
loader: 'css-loader'
|
||||
loader: 'css2json-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -452,6 +490,10 @@ exports[`react configuration > ios > adds ReactRefreshWebpackPlugin when HMR ena
|
||||
{
|
||||
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'
|
||||
@ -465,6 +507,16 @@ exports[`react configuration > ios > adds ReactRefreshWebpackPlugin when HMR ena
|
||||
]
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
defaultVendor: {
|
||||
test: /[\\\\\\\\/]node_modules[\\\\\\\\/]/,
|
||||
priority: -10,
|
||||
name: 'vendor',
|
||||
chunks: 'all'
|
||||
}
|
||||
}
|
||||
},
|
||||
minimizer: [
|
||||
/* config.optimization.minimizer('TerserPlugin') */
|
||||
new TerserPlugin(
|
||||
@ -487,22 +539,27 @@ exports[`react configuration > ios > adds ReactRefreshWebpackPlugin when HMR ena
|
||||
cleanOnceBeforeBuildPatterns: [
|
||||
'__jest__/platforms/ios/__jest__/app/**/*'
|
||||
],
|
||||
verbose: true
|
||||
verbose: false
|
||||
}
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
'global.NS_WEBPACK': true,
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__CSS_PARSER__: '\\"css-tree\\"',
|
||||
__ANDROID__: false,
|
||||
__IOS__: true,
|
||||
'global.isAndroid': false,
|
||||
'global.isIOS': true,
|
||||
process: 'global.process',
|
||||
profile: '() => {}',
|
||||
__DEV__: 'true',
|
||||
__TEST__: 'false',
|
||||
'process.env.NODE_ENV': '\\"development\\"'
|
||||
}
|
||||
),
|
||||
/* config.plugin('BundleAnalyzerPlugin') */
|
||||
new BundleAnalyzerPlugin(),
|
||||
/* config.plugin('WatchStateLoggerPlugin') */
|
||||
new WatchStateLoggerPlugin(),
|
||||
/* config.plugin('ReactRefreshWebpackPlugin') */
|
||||
@ -621,9 +678,9 @@ exports[`react configuration > ios > base config 1`] = `
|
||||
{
|
||||
loader: 'apply-css-loader'
|
||||
},
|
||||
/* config.module.rule('css').use('css-loader') */
|
||||
/* config.module.rule('css').use('css2json-loader') */
|
||||
{
|
||||
loader: 'css-loader'
|
||||
loader: 'css2json-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -631,6 +688,10 @@ exports[`react configuration > ios > base config 1`] = `
|
||||
{
|
||||
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'
|
||||
@ -644,6 +705,16 @@ exports[`react configuration > ios > base config 1`] = `
|
||||
]
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
defaultVendor: {
|
||||
test: /[\\\\\\\\/]node_modules[\\\\\\\\/]/,
|
||||
priority: -10,
|
||||
name: 'vendor',
|
||||
chunks: 'all'
|
||||
}
|
||||
}
|
||||
},
|
||||
minimizer: [
|
||||
/* config.optimization.minimizer('TerserPlugin') */
|
||||
new TerserPlugin(
|
||||
@ -666,22 +737,27 @@ exports[`react configuration > ios > base config 1`] = `
|
||||
cleanOnceBeforeBuildPatterns: [
|
||||
'__jest__/platforms/ios/__jest__/app/**/*'
|
||||
],
|
||||
verbose: true
|
||||
verbose: false
|
||||
}
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
'global.NS_WEBPACK': true,
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__CSS_PARSER__: '\\"css-tree\\"',
|
||||
__ANDROID__: false,
|
||||
__IOS__: true,
|
||||
'global.isAndroid': false,
|
||||
'global.isIOS': true,
|
||||
process: 'global.process',
|
||||
profile: '() => {}',
|
||||
__DEV__: 'true',
|
||||
__TEST__: 'false',
|
||||
'process.env.NODE_ENV': '\\"development\\"'
|
||||
}
|
||||
),
|
||||
/* config.plugin('BundleAnalyzerPlugin') */
|
||||
new BundleAnalyzerPlugin(),
|
||||
/* config.plugin('WatchStateLoggerPlugin') */
|
||||
new WatchStateLoggerPlugin()
|
||||
],
|
||||
|
@ -88,9 +88,9 @@ exports[`vue configuration for android 1`] = `
|
||||
{
|
||||
loader: 'apply-css-loader'
|
||||
},
|
||||
/* config.module.rule('css').use('css-loader') */
|
||||
/* config.module.rule('css').use('css2json-loader') */
|
||||
{
|
||||
loader: 'css-loader'
|
||||
loader: 'css2json-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -98,6 +98,10 @@ exports[`vue configuration for android 1`] = `
|
||||
{
|
||||
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'
|
||||
@ -124,6 +128,16 @@ exports[`vue configuration for android 1`] = `
|
||||
]
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
defaultVendor: {
|
||||
test: /[\\\\\\\\/]node_modules[\\\\\\\\/]/,
|
||||
priority: -10,
|
||||
name: 'vendor',
|
||||
chunks: 'all'
|
||||
}
|
||||
}
|
||||
},
|
||||
minimizer: [
|
||||
/* config.optimization.minimizer('TerserPlugin') */
|
||||
new TerserPlugin(
|
||||
@ -148,19 +162,25 @@ exports[`vue configuration for android 1`] = `
|
||||
cleanOnceBeforeBuildPatterns: [
|
||||
'__jest__/platforms/android/app/src/main/assets/app/**/*'
|
||||
],
|
||||
verbose: true
|
||||
verbose: false
|
||||
}
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
'global.NS_WEBPACK': true,
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__CSS_PARSER__: '\\"css-tree\\"',
|
||||
__ANDROID__: true,
|
||||
__IOS__: false,
|
||||
'global.isAndroid': true,
|
||||
'global.isIOS': false,
|
||||
process: 'global.process',
|
||||
profile: '() => {}'
|
||||
}
|
||||
),
|
||||
/* config.plugin('BundleAnalyzerPlugin') */
|
||||
new BundleAnalyzerPlugin(),
|
||||
/* config.plugin('WatchStateLoggerPlugin') */
|
||||
new WatchStateLoggerPlugin()
|
||||
],
|
||||
@ -260,9 +280,9 @@ exports[`vue configuration for ios 1`] = `
|
||||
{
|
||||
loader: 'apply-css-loader'
|
||||
},
|
||||
/* config.module.rule('css').use('css-loader') */
|
||||
/* config.module.rule('css').use('css2json-loader') */
|
||||
{
|
||||
loader: 'css-loader'
|
||||
loader: 'css2json-loader'
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -270,6 +290,10 @@ exports[`vue configuration for ios 1`] = `
|
||||
{
|
||||
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'
|
||||
@ -296,6 +320,16 @@ exports[`vue configuration for ios 1`] = `
|
||||
]
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
defaultVendor: {
|
||||
test: /[\\\\\\\\/]node_modules[\\\\\\\\/]/,
|
||||
priority: -10,
|
||||
name: 'vendor',
|
||||
chunks: 'all'
|
||||
}
|
||||
}
|
||||
},
|
||||
minimizer: [
|
||||
/* config.optimization.minimizer('TerserPlugin') */
|
||||
new TerserPlugin(
|
||||
@ -320,19 +354,25 @@ exports[`vue configuration for ios 1`] = `
|
||||
cleanOnceBeforeBuildPatterns: [
|
||||
'__jest__/platforms/ios/__jest__/app/**/*'
|
||||
],
|
||||
verbose: true
|
||||
verbose: false
|
||||
}
|
||||
),
|
||||
/* config.plugin('DefinePlugin') */
|
||||
new DefinePlugin(
|
||||
{
|
||||
'global.NS_WEBPACK': true,
|
||||
__DEV__: true,
|
||||
__NS_WEBPACK__: true,
|
||||
__CSS_PARSER__: '\\"css-tree\\"',
|
||||
__ANDROID__: false,
|
||||
__IOS__: true,
|
||||
'global.isAndroid': false,
|
||||
'global.isIOS': true,
|
||||
process: 'global.process',
|
||||
profile: '() => {}'
|
||||
}
|
||||
),
|
||||
/* config.plugin('BundleAnalyzerPlugin') */
|
||||
new BundleAnalyzerPlugin(),
|
||||
/* config.plugin('WatchStateLoggerPlugin') */
|
||||
new WatchStateLoggerPlugin()
|
||||
],
|
||||
|
@ -1,10 +1,8 @@
|
||||
import Config from 'webpack-chain';
|
||||
import { IWebpackEnv, Platform } from '../index';
|
||||
import { IWebpackEnv } from '../index';
|
||||
import {
|
||||
getAbsoluteDistPath,
|
||||
getDistPath,
|
||||
getEntryPath,
|
||||
getPackageJson,
|
||||
getPlatform,
|
||||
} from '../helpers/project';
|
||||
|
||||
@ -17,19 +15,21 @@ import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
|
||||
export default function (config: Config, env: IWebpackEnv): Config {
|
||||
const entryPath = getEntryPath();
|
||||
const platform = getPlatform();
|
||||
const packageJson = getPackageJson();
|
||||
const mode = env.production ? 'production' : 'development';
|
||||
|
||||
// set mode
|
||||
config.mode(mode);
|
||||
|
||||
// package.json is generated by the CLI with runtime options
|
||||
// this ensures it's not included in the bundle
|
||||
config.externals(['package.json']);
|
||||
|
||||
// todo: devtool
|
||||
config.devtool('inline-source-map');
|
||||
|
||||
// todo: figure out easiest way to make "node" target work in ns,
|
||||
// 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').add(entryPath);
|
||||
@ -62,11 +62,6 @@ export default function (config: Config, env: IWebpackEnv): Config {
|
||||
priority: -10,
|
||||
name: 'vendor',
|
||||
chunks: 'all',
|
||||
// test: (module) => {
|
||||
// const moduleName = module.nameForCondition ? module.nameForCondition() : '';
|
||||
// return /[\\/]node_modules[\\/]/.test(moduleName);
|
||||
// },
|
||||
// enforce: true
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -74,6 +69,7 @@ export default function (config: Config, env: IWebpackEnv): Config {
|
||||
// look for loaders in
|
||||
// - node_modules/@nativescript/webpack/dist/loaders
|
||||
// - node_modules
|
||||
// allows for cleaner rules, without having to specify full paths to loaders
|
||||
config.resolveLoader.modules
|
||||
.add('node_modules/@nativescript/webpack/dist/loaders')
|
||||
.add('node_modules');
|
||||
@ -149,6 +145,9 @@ export default function (config: Config, env: IWebpackEnv): Config {
|
||||
config.module
|
||||
.rule('scss')
|
||||
.test(/\.scss$/)
|
||||
.use('apply-css-loader')
|
||||
.loader('apply-css-loader')
|
||||
.end()
|
||||
.use('css2json-loader')
|
||||
.loader('css2json-loader')
|
||||
.end()
|
||||
@ -159,18 +158,22 @@ export default function (config: Config, env: IWebpackEnv): Config {
|
||||
config.plugin('CleanWebpackPlugin').use(CleanWebpackPlugin, [
|
||||
{
|
||||
cleanOnceBeforeBuildPatterns: [`${getAbsoluteDistPath()}/**/*`],
|
||||
verbose: true,
|
||||
verbose: !!env.verbose,
|
||||
},
|
||||
]);
|
||||
|
||||
// todo: refine defaults
|
||||
config.plugin('DefinePlugin').use(DefinePlugin, [
|
||||
{
|
||||
'global.NS_WEBPACK': true,
|
||||
'global.isAndroid': platform === 'android',
|
||||
'global.isIOS': platform === 'ios',
|
||||
__DEV__: mode === 'development',
|
||||
__NS_WEBPACK__: true,
|
||||
__CSS_PARSER__: JSON.stringify('css-tree'), // todo: replace from config value
|
||||
__ANDROID__: platform === 'android',
|
||||
__IOS__: platform === 'ios',
|
||||
/* for compat only */ 'global.isAndroid': platform === 'android',
|
||||
/* for compat only */ 'global.isIOS': platform === 'ios',
|
||||
process: 'global.process',
|
||||
profile: '() => {}',
|
||||
/* todo: remove if fixed in core? */ profile: '() => {}',
|
||||
},
|
||||
]);
|
||||
|
||||
@ -183,6 +186,7 @@ export default function (config: Config, env: IWebpackEnv): Config {
|
||||
// },
|
||||
// ]);
|
||||
|
||||
// todo: make opt-in with a flag
|
||||
config.plugin('BundleAnalyzerPlugin').use(BundleAnalyzerPlugin);
|
||||
|
||||
// add the WatchStateLogger plugin used to notify the CLI of build state
|
||||
|
@ -8,9 +8,11 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
|
||||
base(config, env);
|
||||
|
||||
const platform = getPlatform();
|
||||
const mode = env.production ? 'production' : 'development';
|
||||
const production = mode === 'production';
|
||||
|
||||
// todo: use env
|
||||
let isAnySourceMapEnabled = true;
|
||||
let production = false;
|
||||
|
||||
config.resolve.extensions.prepend('.tsx').prepend(`.${platform}.tsx`);
|
||||
config.resolve.alias.set('react-dom', 'react-nativescript');
|
||||
@ -30,15 +32,12 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
|
||||
config.plugin('DefinePlugin').tap((args) => {
|
||||
args[0] = merge(args[0], {
|
||||
/** For various libraries in the React ecosystem. */
|
||||
__DEV__: production ? 'false' : 'true',
|
||||
__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(
|
||||
production ? 'production' : 'development'
|
||||
),
|
||||
'process.env.NODE_ENV': JSON.stringify(mode),
|
||||
});
|
||||
|
||||
return args;
|
||||
|
@ -23,6 +23,8 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
|
||||
.tap((options) => {
|
||||
return {
|
||||
...options,
|
||||
// todo: should be a compiler object
|
||||
// but we want it as an external dependency
|
||||
compiler: 'nativescript-vue-template-compiler',
|
||||
};
|
||||
})
|
||||
|
24
packages/webpack5/src/helpers/dependencies.ts
Normal file
24
packages/webpack5/src/helpers/dependencies.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { getPackageJson, getProjectRootPath } from './project';
|
||||
import path from 'path';
|
||||
|
||||
export function getAllDependencies(): string[] {
|
||||
const packageJSON = getPackageJson();
|
||||
console.log(packageJSON);
|
||||
|
||||
return [
|
||||
...Object.keys(packageJSON.dependencies ?? {}),
|
||||
...Object.keys(packageJSON.devDependencies ?? {}),
|
||||
];
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
// 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')}
|
||||
`);
|
||||
}
|
36
packages/webpack5/src/helpers/externalConfigs.ts
Normal file
36
packages/webpack5/src/helpers/externalConfigs.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import dedent from 'ts-dedent';
|
||||
import * as lib from '../index';
|
||||
import { error, info } from './log';
|
||||
import { getAllDependencies, getDependencyPath } from './dependencies';
|
||||
|
||||
export function applyExternalConfigs() {
|
||||
getAllDependencies().forEach((dependency) => {
|
||||
const packagePath = getDependencyPath(dependency);
|
||||
const configPath = path.join(packagePath, 'nativescript.webpack.js');
|
||||
|
||||
if (fs.existsSync(configPath)) {
|
||||
info(`Discovered config: ${configPath}`);
|
||||
|
||||
try {
|
||||
const externalConfig = require(configPath);
|
||||
|
||||
if (typeof externalConfig === 'function') {
|
||||
externalConfig(lib);
|
||||
} else {
|
||||
// todo: warn user
|
||||
// todo: perhaps support exported objects to merge into config?
|
||||
}
|
||||
} catch (err) {
|
||||
error(
|
||||
dedent`
|
||||
Unable to apply config: ${configPath}.
|
||||
Error is:
|
||||
`,
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
@ -1,18 +1,44 @@
|
||||
import { defaultConfigs } from '@nativescript/webpack';
|
||||
import { getAllDependencies } from './dependencies';
|
||||
import { error } from './log';
|
||||
import dedent from 'ts-dedent';
|
||||
|
||||
export function determineProjectFlavor(): keyof typeof defaultConfigs {
|
||||
// todo;
|
||||
export function determineProjectFlavor(): keyof typeof defaultConfigs | false {
|
||||
const dependencies = getAllDependencies();
|
||||
|
||||
// error(`
|
||||
// Could not determine project flavor.
|
||||
//
|
||||
// Please use webpack.useConfig('<flavor>') to explicitly set the base config.
|
||||
// `, {
|
||||
// possibleCauses: [
|
||||
// 'Not in a NativeScript project',
|
||||
// 'The project is not at the current working directory'
|
||||
// ]
|
||||
// })
|
||||
if (dependencies.includes('nativescript-vue')) {
|
||||
return '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(dedent`
|
||||
Could not determine project flavor.
|
||||
Please use webpack.useConfig('<flavor>') to explicitly set the base config.
|
||||
`);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
23
packages/webpack5/src/helpers/log.ts
Normal file
23
packages/webpack5/src/helpers/log.ts
Normal file
@ -0,0 +1,23 @@
|
||||
// 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')}
|
||||
// `);
|
||||
// }
|
||||
|
||||
export function error(...data: any) {
|
||||
console.error(`[@nativescript/webpack]`, ...data);
|
||||
}
|
||||
|
||||
export function warn(...data: any) {
|
||||
console.warn(`[@nativescript/webpack]`, ...data);
|
||||
}
|
||||
|
||||
export function info(...data: any) {
|
||||
console.info(`[@nativescript/webpack]`, ...data);
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import { env, Platform } from '../index';
|
||||
import { resolve, basename } from 'path';
|
||||
import { error } from './log';
|
||||
|
||||
export function getProjectRootPath(): string {
|
||||
// todo: find actual path?
|
||||
@ -42,8 +43,7 @@ export function getPlatform(): Platform {
|
||||
return 'ios';
|
||||
}
|
||||
|
||||
// todo: maybe no throw?
|
||||
throw new Error('You need to provide a target platform!');
|
||||
error('You need to provide a target platform!');
|
||||
}
|
||||
|
||||
interface IPackageJson {
|
||||
|
@ -1,8 +1,9 @@
|
||||
import Config from 'webpack-chain';
|
||||
import webpack from 'webpack';
|
||||
import { highlight } from 'cli-highlight';
|
||||
import { configs } from './configuration';
|
||||
import { determineProjectFlavor } from './helpers/flavor';
|
||||
import { highlight } from 'cli-highlight';
|
||||
import { applyExternalConfigs } from './helpers/externalConfigs';
|
||||
|
||||
export type Platform = 'android' | 'ios' | string;
|
||||
|
||||
@ -49,11 +50,18 @@ export function useConfig(config: keyof typeof defaultConfigs | false) {
|
||||
}
|
||||
}
|
||||
|
||||
export function chainWebpack(chainFn: (config: Config, env: IWebpackEnv) => any) {
|
||||
export function chainWebpack(
|
||||
chainFn: (config: Config, env: IWebpackEnv) => any
|
||||
) {
|
||||
webpackChains.push(chainFn);
|
||||
}
|
||||
|
||||
export function mergeWebpack(mergeFn: (config: Partial<webpack.Configuration>, env: IWebpackEnv) => any | Partial<webpack.Configuration>) {
|
||||
export function mergeWebpack(
|
||||
mergeFn: (
|
||||
config: Partial<webpack.Configuration>,
|
||||
env: IWebpackEnv
|
||||
) => any | Partial<webpack.Configuration>
|
||||
) {
|
||||
webpackMerges.push(mergeFn);
|
||||
}
|
||||
|
||||
@ -64,6 +72,10 @@ export function resolveChainableConfig() {
|
||||
useConfig(determineProjectFlavor());
|
||||
}
|
||||
|
||||
// apply configs from dependencies
|
||||
// todo: allow opt-out
|
||||
applyExternalConfigs();
|
||||
|
||||
// this applies all chain configs
|
||||
webpackChains.forEach((chainFn) => {
|
||||
return chainFn(config, env);
|
||||
|
@ -11,33 +11,29 @@ export default function loader(content, map) {
|
||||
?.slice(this.loaderIndex)
|
||||
.some(({ path }) => path.includes(loader));
|
||||
};
|
||||
// add a tag to the applied css
|
||||
const tag =
|
||||
this.mode === 'development' ? `, ${JSON.stringify(this.resourcePath)}` : '';
|
||||
|
||||
if (hasLoader('apply-css-loader')) {
|
||||
// add a tag to the applied css
|
||||
const tag =
|
||||
this.mode === 'development'
|
||||
? `, ${JSON.stringify(this.resourcePath)}`
|
||||
: '';
|
||||
content = dedent`
|
||||
${content}
|
||||
const { addTaggedAdditionalCSS } = require("@nativescript/core/ui/styling/style-scope");
|
||||
addTaggedAdditionalCSS(___CSS2JSON_LOADER_EXPORT___${tag})
|
||||
${content}
|
||||
const { addTaggedAdditionalCSS } = require("@nativescript/core/ui/styling/style-scope");
|
||||
addTaggedAdditionalCSS(___CSS2JSON_LOADER_EXPORT___${tag})
|
||||
`;
|
||||
} else if (hasLoader('css-loader')) {
|
||||
content = dedent`
|
||||
${content}
|
||||
// apply css
|
||||
const { Application } = require("@nativescript/core");
|
||||
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
|
||||
Application.addCss(cssExport[1]);
|
||||
}
|
||||
});
|
||||
}
|
||||
`;
|
||||
${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]${tag});
|
||||
}
|
||||
});
|
||||
}
|
||||
`;
|
||||
} else {
|
||||
this.emitWarning(new Error(cssLoaderWarning));
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ export default function loader(content: string, map: any) {
|
||||
|
||||
const ast = parse(content);
|
||||
|
||||
// todo: revise if this is necessary
|
||||
// todo: perhaps use postCSS and just build imports into a single file?
|
||||
let dependencies = [];
|
||||
getImportRules(ast)
|
||||
.map(extractUrlFromRule)
|
||||
@ -37,9 +39,7 @@ export default function loader(content: string, map: any) {
|
||||
const code = dedent`
|
||||
/* CSS2JSON */
|
||||
${dependencies.join('\n')}
|
||||
|
||||
const ___CSS2JSON_LOADER_EXPORT___ = ${str}
|
||||
|
||||
export default ___CSS2JSON_LOADER_EXPORT___
|
||||
`;
|
||||
this.callback(
|
||||
|
@ -1,3 +1,6 @@
|
||||
import webpack from 'webpack';
|
||||
|
||||
const id = 'WatchStateLoggerPlugin';
|
||||
export enum messages {
|
||||
compilationComplete = 'Webpack compilation complete.',
|
||||
startWatching = 'Webpack compilation complete. Watching for file changes.',
|
||||
@ -13,15 +16,20 @@ export class WatchStateLoggerPlugin {
|
||||
|
||||
apply(compiler) {
|
||||
const plugin = this;
|
||||
compiler.hooks.watchRun.tapAsync('WatchStateLoggerPlugin', function (compiler, callback) {
|
||||
|
||||
compiler.hooks.watchRun.tapAsync(id, function (compiler, callback) {
|
||||
plugin.isRunningWatching = true;
|
||||
|
||||
if (plugin.isRunningWatching) {
|
||||
console.log(messages.changeDetected);
|
||||
}
|
||||
process.send && process.send(messages.changeDetected, (error) => null);
|
||||
|
||||
notify(messages.changeDetected);
|
||||
|
||||
callback();
|
||||
});
|
||||
compiler.hooks.afterEmit.tapAsync('WatchStateLoggerPlugin', function (compilation, callback) {
|
||||
|
||||
compiler.hooks.afterEmit.tapAsync(id, function (compilation, callback) {
|
||||
callback();
|
||||
|
||||
if (plugin.isRunningWatching) {
|
||||
@ -30,18 +38,20 @@ export class WatchStateLoggerPlugin {
|
||||
console.log(messages.compilationComplete);
|
||||
}
|
||||
|
||||
const emittedFiles = Object.keys(compilation.assets).filter((assetKey) => compilation.assets[assetKey].emitted);
|
||||
const emittedFiles = Object.keys(compilation.assets).filter(
|
||||
(assetKey) => compilation.assets[assetKey].emitted
|
||||
);
|
||||
const chunkFiles = getChunkFiles(compilation);
|
||||
|
||||
process.send && process.send(messages.compilationComplete, (error) => null);
|
||||
notify(messages.compilationComplete);
|
||||
|
||||
// Send emitted files so they can be LiveSynced if need be
|
||||
process.send && process.send({ emittedFiles, chunkFiles, hash: compilation.hash }, (error) => null);
|
||||
notify({ emittedFiles, chunkFiles, hash: compilation.hash });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getChunkFiles(compilation) {
|
||||
function getChunkFiles(compilation: webpack.Compilation) {
|
||||
const chunkFiles = [];
|
||||
try {
|
||||
compilation.chunks.forEach((chunk) => {
|
||||
@ -57,3 +67,17 @@ function getChunkFiles(compilation) {
|
||||
|
||||
return chunkFiles;
|
||||
}
|
||||
|
||||
function notify(message: any) {
|
||||
if (!process.send) {
|
||||
return;
|
||||
}
|
||||
|
||||
process.send(message, (error) => {
|
||||
if (error) {
|
||||
console.error(`[${id}] Process Send Error: `, error);
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user