nativescript-dev-webpack icon indicating copy to clipboard operation
nativescript-dev-webpack copied to clipboard

Error: Cannot find module '@nativescript/webpack/nativescript-target'

Open pieveee opened this issue 4 years ago • 0 comments

Environment Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):

  • CLI: 8.0.2
  • Android Runtime: 8.0.0
  • iOS Runtime: none
  • Plugin(s): none
  • Node.js: 14.17.1

package.json:

{
  "name": "aurora-spa",
  "version": "0.0.0",
  "scripts": {
    "android": "ns run android --no-hmr",
    "ios": "ns run ios --no-hmr",
    "mobile": "ns run",
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@nativescript/angular": "~11.8.0",
    "@nativescript/core": "~8.0.0",
    "@nativescript/theme": "~2.5.0",
    "reflect-metadata": "~0.1.12",
    "tslib": "^1.10.0",
    "@angular/animations": "~12.0.5",
    "@angular/common": "~12.0.5",
    "@angular/compiler": "~12.0.5",
    "@angular/core": "~12.0.5",
    "@angular/forms": "~12.0.5",
    "@angular/platform-browser": "~12.0.5",
    "@angular/platform-browser-dynamic": "~12.0.5",
    "@angular/router": "~12.0.5",
    "@auth0/angular-jwt": "5.0.2",
    "@fortawesome/angular-fontawesome": "^0.9.0",
    "@fortawesome/fontawesome-svg-core": "^1.2.28",
    "@fortawesome/free-regular-svg-icons": "^5.15.1",
    "@fortawesome/free-solid-svg-icons": "^5.15.1",
    "@ngrx/effects": "^12.1.0",
    "@ngrx/store": "^12.1.0",
    "axios": "^0.19.1",
    "bootstrap": "^4.4.1",
    "core-js": "^2.5.4",
    "ng-sapphiredb": "^3.1.8",
    "ngx-bootstrap": "^5.6.1",
    "rxjs": "~6.6.7",
    "sapphiredb": "^3.0.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular/cli": "~12.0.5",
    "@angular/compiler-cli": "~12.0.5",
    "@angular/language-service": "~12.0.5",
    "@nativescript/android": "8.0.0",
    "@nativescript/schematics": "^11.2.0",
    "@nativescript/tslint-rules": "~0.0.5",
    "@ngrx/store-devtools": "^12.1.0",
    "@types/jasmine": "~2.8.8",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^12.11.1",
    "codelyzer": "^5.1.2",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~5.0.0",
    "karma": "~6.3.4",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~3.0.2",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "protractor": "~7.0.0",
    "ts-node": "~7.0.0",
    "tslint": "~6.1.0",
    "typescript": "~4.2.4",
    "@nativescript/webpack": "~5.0.0-beta.0",
    "@ngtools/webpack": "~10.0.0"
  },
  "main": "./src/main.tns.ts"
}

webpack.config.js:

const { join, relative, resolve, sep, dirname } = require('path');
const fs = require('fs');

const webpack = require('webpack');
const nsWebpack = require('@nativescript/webpack');
const nativescriptTarget = require('@nativescript/webpack/nativescript-target');
const { nsSupportHmrNg } = require('@nativescript/webpack/transformers/ns-support-hmr-ng');
const { nsTransformNativeClassesNg } = require('@nativescript/webpack/transformers/ns-transform-native-classes-ng');
const { parseWorkspaceConfig, hasConfigurations } = require('@nativescript/webpack/helpers/angular-config-parser');
const { getMainModulePath } = require('@nativescript/webpack/utils/ast-utils');
const { getNoEmitOnErrorFromTSConfig, getCompilerOptionsFromTSConfig } = require('@nativescript/webpack/utils/tsconfig-utils');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const { NativeScriptWorkerPlugin } = require('nativescript-worker-loader/NativeScriptWorkerPlugin');
const TerserPlugin = require('terser-webpack-plugin');
const { getAngularCompilerPlugin } = require('@nativescript/webpack/plugins/NativeScriptAngularCompilerPlugin');
const hashSalt = Date.now().toString();

module.exports = (env) => {
	const platform = env && ((env.android && 'android') || (env.ios && 'ios'));
	if (!platform) {
		throw new Error('You need to provide a target platform!');
	}

	const AngularCompilerPlugin = getAngularCompilerPlugin(platform);
	const projectRoot = __dirname;

	// Default destination inside platforms/<platform>/...
	const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot));

	const {
		// The 'appPath' and 'appResourcesPath' values are fetched from
		// the nsconfig.json configuration file
		// when bundling with `tns run android|ios --bundle`.
		appPath = 'src',
		appResourcesPath = 'App_Resources',

		// You can provide the following flags when running 'tns run android|ios'
		snapshot, // --env.snapshot,
		production, // --env.production
		configuration, // --env.configuration (consistent with angular cli usage)
		projectName, // --env.projectName (drive configuration through angular projects)
		uglify, // --env.uglify
		report, // --env.report
		sourceMap, // --env.sourceMap
		hiddenSourceMap, // --env.hiddenSourceMap
		hmr, // --env.hmr,
		unitTesting, // --env.unitTesting
		testing, // --env.testing
		verbose, // --env.verbose
		ci, // --env.ci
		snapshotInDocker, // --env.snapshotInDocker
		skipSnapshotTools, // --env.skipSnapshotTools
		compileSnapshot, // --env.compileSnapshot
		appComponents = [],
		entries = {},
	} = env;

	const { fileReplacements, copyReplacements } = parseWorkspaceConfig(platform, configuration, projectName);

	const useLibs = compileSnapshot;
	const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap;
	const externals = nsWebpack.getConvertedExternals(env.externals);
	const appFullPath = resolve(projectRoot, appPath);
	const appResourcesFullPath = resolve(projectRoot, appResourcesPath);
	let tsConfigName = 'tsconfig.json';
	let tsConfigPath = resolve(projectRoot, tsConfigName);
	const tsConfigTnsName = 'tsconfig.tns.json';
	const tsConfigTnsPath = resolve(projectRoot, tsConfigTnsName);
	if (fs.existsSync(tsConfigTnsPath)) {
		// support shared angular app configurations
		tsConfigName = tsConfigTnsName;
		tsConfigPath = tsConfigTnsPath;
	}
	const tsConfigEnvName = 'tsconfig.env.json';
	const tsConfigEnvPath = resolve(projectRoot, tsConfigEnvName);
	if (hasConfigurations(configuration) && fs.existsSync(tsConfigEnvPath)) {
		// when configurations are used, switch to environments supported config
		tsConfigName = tsConfigEnvName;
		tsConfigPath = tsConfigEnvPath;
	}
	const entryModule = `${nsWebpack.getEntryModule(appFullPath, platform)}.ts`;
	const entryPath = `.${sep}${entryModule}`;
	Object.assign(entries, { bundle: entryPath }, entries);
	const areCoreModulesExternal = Array.isArray(env.externals) && env.externals.some((e) => e.indexOf('@nativescript') > -1);
	if (platform === 'ios' && !areCoreModulesExternal && !testing) {
		entries['tns_modules/inspector_modules'] = '@nativescript/core/inspector_modules';
	}

	const compilerOptions = getCompilerOptionsFromTSConfig(tsConfigPath);
	nsWebpack.processTsPathsForScopedModules({ compilerOptions });
	nsWebpack.processTsPathsForScopedAngular({ compilerOptions });

	const ngCompilerTransformers = [nsTransformNativeClassesNg];
	const additionalLazyModuleResources = [];

	const copyIgnore = { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] };
	const copyTargets = [{ from: { glob: 'assets/**', dot: false } }, { from: { glob: 'fonts/**', dot: false } }, ...copyReplacements];

	if (!production) {
		// for development purposes only
		// for example, include mock json folder
		// copyTargets.push({ from: 'tools/mockdata', to: 'assets/mockdata' });

		if (hmr) {
			ngCompilerTransformers.push(nsSupportHmrNg);
		}
	}

	// when "@angular/core" is external, it's not included in the bundles. In this way, it will be used
	// directly from node_modules and the Angular modules loader won't be able to resolve the lazy routes
	// fixes https://github.com/NativeScript/nativescript-cli/issues/4024
	if (env.externals && env.externals.indexOf('@angular/core') > -1) {
		const appModuleRelativePath = getMainModulePath(resolve(appFullPath, entryModule), tsConfigName);
		if (appModuleRelativePath) {
			const appModuleFolderPath = dirname(resolve(appFullPath, appModuleRelativePath));
			// include the new lazy loader path in the allowed ones
			additionalLazyModuleResources.push(appModuleFolderPath);
		}
	}

	const ngCompilerPlugin = new AngularCompilerPlugin({
		hostReplacementPaths: nsWebpack.getResolver([platform, 'tns']),
		platformTransformers: ngCompilerTransformers.map((t) => t(() => ngCompilerPlugin, resolve(appFullPath, entryModule), projectRoot)),
		mainPath: join(appFullPath, entryModule),
		tsConfigPath,
		skipCodeGeneration: false,
		sourceMap: !!isAnySourceMapEnabled,
		additionalLazyModuleResources: additionalLazyModuleResources,
		compilerOptions: { paths: compilerOptions.paths },
	});

	let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist);

	const itemsToClean = [`${dist}/**/*`];
	if (platform === 'android') {
		itemsToClean.push(`${join(projectRoot, 'platforms', 'android', 'app', 'src', 'main', 'assets', 'snapshots')}`);
		itemsToClean.push(`${join(projectRoot, 'platforms', 'android', 'app', 'build', 'configurations', 'nativescript-android-snapshot')}`);
	}

	const noEmitOnErrorFromTSConfig = getNoEmitOnErrorFromTSConfig(tsConfigName);

	// Add your custom Activities, Services and other android app components here.
	appComponents.push('@nativescript/core/ui/frame', '@nativescript/core/ui/frame/activity');

	nsWebpack.processAppComponents(appComponents, platform);
	const config = {
		mode: production ? 'production' : 'development',
		context: appFullPath,
		externals,
		watchOptions: {
			ignored: [
				appResourcesFullPath,
				// Don't watch hidden files
				'**/.*',
			],
		},
		target: nativescriptTarget,
		entry: entries,
		output: {
			pathinfo: false,
			path: dist,
			sourceMapFilename,
			libraryTarget: 'commonjs2',
			filename: '[name].js',
			globalObject: 'global',
			hashSalt,
		},
		resolve: {
			extensions: ['.ts', '.js', '.scss', '.css'],
			// Resolve {N} system modules from @nativescript/core
			modules: [resolve(__dirname, 'node_modules/@nativescript/core'), resolve(__dirname, 'node_modules'), 'node_modules/@nativescript/core', 'node_modules'],
			alias: {
				'~/package.json': resolve(projectRoot, 'package.json'),
				'~': appFullPath,
				'tns-core-modules': '@nativescript/core',
				'nativescript-angular': '@nativescript/angular',
				...fileReplacements,
			},
			symlinks: true,
		},
		resolveLoader: {
			symlinks: false,
		},
		node: {
			// Disable node shims that conflict with NativeScript
			http: false,
			timers: false,
			setImmediate: false,
			fs: 'empty',
			__dirname: false,
		},
		devtool: hiddenSourceMap ? 'hidden-source-map' : sourceMap ? 'inline-source-map' : 'none',
		optimization: {
			runtimeChunk: 'single',
			noEmitOnErrors: noEmitOnErrorFromTSConfig,
			splitChunks: {
				cacheGroups: {
					vendor: {
						name: 'vendor',
						chunks: 'all',
						test: (module, chunks) => {
							const moduleName = module.nameForCondition ? module.nameForCondition() : '';
							return /[\\/]node_modules[\\/]/.test(moduleName) || appComponents.some((comp) => comp === moduleName);
						},
						enforce: true,
					},
				},
			},
			minimize: !!uglify,
			minimizer: [
				new TerserPlugin({
					parallel: true,
					cache: !ci,
					sourceMap: isAnySourceMapEnabled,
					terserOptions: {
						output: {
							comments: false,
							semicolons: !isAnySourceMapEnabled,
						},
						compress: {
							// The Android SBG has problems parsing the output
							// when these options are enabled
							collapse_vars: platform !== 'android',
							sequences: platform !== 'android',
							// For v8 Compatibility
							keep_infinity: true, // for V8
							reduce_funcs: false, // for V8
							// custom
							drop_console: production,
							drop_debugger: true,
							ecma: 6,
							global_defs: {
								__UGLIFIED__: true,
							},
						},
						// Required for Element Level CSS, Observable Events, & Android Frame
						keep_classnames: true,
						// custom
						ecma: 6,
						safari10: platform !== 'android',
					},
				}),
			],
		},
		module: {
			rules: [
				{
					include: join(appFullPath, entryPath),
					use: [
						// Require all Android app components
						platform === 'android' && {
							loader: '@nativescript/webpack/helpers/android-app-components-loader',
							options: { modules: appComponents },
						},

						{
							loader: '@nativescript/webpack/bundle-config-loader',
							options: {
								angular: true,
								loadCss: !snapshot, // load the application css if in debug mode
								unitTesting,
								appFullPath,
								projectRoot,
								ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform),
							},
						},
					].filter((loader) => !!loader),
				},

				{ test: /\.html$|\.xml$/, use: 'raw-loader' },

				{
					test: /[\/|\\]app\.css$/,
					use: [
						'@nativescript/webpack/helpers/style-hot-loader',
						{
							loader: '@nativescript/webpack/helpers/css2json-loader',
							options: { useForImports: true },
						},
					],
				},
				{
					test: /[\/|\\]app\.scss$/,
					use: [
						'@nativescript/webpack/helpers/style-hot-loader',
						{
							loader: '@nativescript/webpack/helpers/css2json-loader',
							options: { useForImports: true },
						},
						'sass-loader',
					],
				},

				// Angular components reference css files and their imports using raw-loader
				{ test: /\.css$/, exclude: /[\/|\\]app\.css$/, use: 'raw-loader' },
				{
					test: /\.scss$/,
					exclude: /[\/|\\]app\.scss$/,
					use: ['raw-loader', 'resolve-url-loader', 'sass-loader'],
				},

				{
					test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
					use: ['@nativescript/webpack/helpers/moduleid-compat-loader', '@nativescript/webpack/helpers/lazy-ngmodule-hot-loader', '@ngtools/webpack'],
				},

				// Mark files inside `@angular/core` as using SystemJS style dynamic imports.
				// Removing this will cause deprecation warnings to appear.
				{
					test: /[\/\\]@angular[\/\\]core[\/\\].+\.js$/,
					parser: { system: true },
				},
			],
		},
		plugins: [
			// Define useful constants like TNS_WEBPACK
			new webpack.DefinePlugin({
				'global.TNS_WEBPACK': 'true',
				'global.isAndroid': platform === 'android',
				'global.isIOS': platform === 'ios',
				process: 'global.process',
			}),
			// Remove all files from the out dir.
			new CleanWebpackPlugin({
				cleanOnceBeforeBuildPatterns: itemsToClean,
				verbose: !!verbose,
			}),
			// Copy assets
			new CopyWebpackPlugin([...copyTargets, { from: { glob: '**/*.jpg', dot: false } }, { from: { glob: '**/*.png', dot: false } }], copyIgnore),
			new nsWebpack.GenerateNativeScriptEntryPointsPlugin('bundle'),
			// For instructions on how to set up workers with webpack
			// check out https://github.com/nativescript/worker-loader
			new NativeScriptWorkerPlugin(),
			ngCompilerPlugin,
			// Does IPC communication with the {N} CLI to notify events when running in watch mode.
			new nsWebpack.WatchStateLoggerPlugin(),
		],
	};

	if (report) {
		// Generate report files for bundles content
		config.plugins.push(
			new BundleAnalyzerPlugin({
				analyzerMode: 'static',
				openAnalyzer: false,
				generateStatsFile: true,
				reportFilename: resolve(projectRoot, 'report', `report.html`),
				statsFilename: resolve(projectRoot, 'report', `stats.json`),
			})
		);
	}

	if (snapshot) {
		config.plugins.push(
			new nsWebpack.NativeScriptSnapshotPlugin({
				chunk: 'vendor',
				angular: true,
				requireModules: ['reflect-metadata', '@angular/platform-browser', '@angular/core', '@angular/common', '@angular/router', '@nativescript/angular'],
				projectRoot,
				webpackConfig: config,
				snapshotInDocker,
				skipSnapshotTools,
				useLibs,
			})
		);
	}

	if (!production && hmr) {
		config.plugins.push(new webpack.HotModuleReplacementPlugin());
	}

	return config;
};

Describe the bug When I try to run ns run android I get the following error:

C:\Git\aurora-spa>ns run android
Searching for devices...
Preparing project...
Error: Cannot find module '@nativescript/webpack/nativescript-target'
Require stack:
- C:\Git\aurora-spa\webpack.config.js
- C:\Git\aurora-spa\node_modules\@nativescript\webpack\dist\bin\index.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:902:15)
    at Function.Module._load (internal/modules/cjs/loader.js:746:27)
    at Module.require (internal/modules/cjs/loader.js:974:19)
    at require (internal/modules/cjs/helpers.js:92:18)
    at Object.<anonymous> (C:\Git\aurora-spa\webpack.config.js:6:28)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:14)
    at Module.require (internal/modules/cjs/loader.js:974:19)
    at require (internal/modules/cjs/helpers.js:92:18)
    at Command.<anonymous> (C:\Git\aurora-spa\node_modules\@nativescript\webpack\dist\bin\index.js:60:25)
    at Command.listener [as _actionHandler] (C:\Git\aurora-spa\node_modules\commander\index.js:922:31)
    at Command._parseCommand (C:\Git\aurora-spa\node_modules\commander\index.js:1503:14)
    at Command._dispatchSubcommand (C:\Git\aurora-spa\node_modules\commander\index.js:1443:18)
    at Command._parseCommand (C:\Git\aurora-spa\node_modules\commander\index.js:1460:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'C:\\Git\\aurora-spa\\webpack.config.js',
    'C:\\Git\\aurora-spa\\node_modules\\@nativescript\\webpack\\dist\\bin\\index.js'
  ]
}
No configuration!
Executing webpack failed with exit code 0.

To Reproduce Run the following command: ns run android.

Expected behavior Runs project on emulator.

pieveee avatar Jun 27 '21 18:06 pieveee