如何解决加载程序 app.component.html 中的 Nativescript 错误未返回字符串
环境
- 命令行界面:7.2.1
- iOS 运行时:tns-ios@6.5.4
- XCode 版本:12.3
- 角度版本:11.0.1
描述错误
ns prepare ios
导致加载器“.../app.component.html”中的 ERROR 未返回字符串。执行 webpack 失败,退出代码为 2。
显然这与 webpack 相关,但我的 webpack 是使用 Nativescript 和 XCode 12.3 升级指南自动生成的。
其他背景 我的日志转储在这里:
Preparing project...
Project dir from hooksArgs is: /Users/westdabestdb/Desktop/projectname.
Hooks directories: [ '/Users/westdabestdb/Desktop/projectname/hooks' ]
BeforeHookName for command watch is before-watch
spawn: /usr/local/bin/node "--max_old_space_size=4096" "--preserve-symlinks" "/Users/westdabestdb/Desktop/projectname/node_modules/webpack/bin/webpack.js" "--config=/Users/westdabestdb/Desktop/projectname/webpack.config.js" "--env.hmr" "--env.externals=~/package.json" "--env.externals=package.json" "--env.ios" "--env.appPath=src" "--env.appResourcesPath=App_Resources" "--env.nativescriptLibPath=/usr/local/lib/node_modules/nativescript/lib/nativescript-cli-lib.js" "--env.verbose" "--env.sourceMap" "--watch"
File change detected. Starting incremental webpack compilation...
Message from webpack File change detected. Starting incremental webpack compilation...
Hash: 91ef17259bf9c65391b5
Version: webpack 4.44.2
Time: 10376ms
Built at: 03/12/2021 5:12:17 PM
4 assets
Entrypoint bundle = runtime.js vendor.js bundle.js
Entrypoint tns_modules/@nativescript/core/inspector_modules = runtime.js vendor.js tns_modules/@nativescript/core/inspector_modules.js
[./app.scss] 120 KiB {bundle} [built]
[./main.ts] 910 bytes {bundle} [built]
[~/package.json] external "~/package.json" 42 bytes {bundle} {tns_modules/@nativescript/core/inspector_modules} [optional] [built]
+ 331 hidden modules
ERROR in The loader "/Users/westdabestdb/Desktop/projectname/src/app/app.component.html" didn't return a string.
还有 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 => {
// Add your custom Activities,Services and other Android app components here.
const appComponents = [
"@nativescript/core/ui/frame","@nativescript/core/ui/frame/activity"
];
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
} = 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}`;
const entries = { bundle: entryPath };
const areCoreModulesExternal =
Array.isArray(env.externals) &&
env.externals.some(e => e.indexOf('@nativescript') > -1);
if (platform === 'ios' && !areCoreModulesExternal && !testing) {
entries['tns_modules/@nativescript/core/inspector_modules'] =
'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/**',...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,projectRoot)
),mainPath: join(appFullPath,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,'build','configurations','nativescript-android-snapshot'
)}`
);
}
const noEmitOnErrorFromTSConfig = getNoEmitOnErrorFromTSConfig(tsConfigName);
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',// custom
drop_console: true,drop_debugger: true,ecma: 6,keep_infinity: platform === 'android',// for Chrome/V8
reduce_funcs: platform !== 'android',// for Chrome/V8
global_defs: {
__UGLIFIED__: 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$/,'sass-loader',// Angular components reference css files and their imports using raw-loader
{ test: /\.css$/,exclude: /[\/|\\]app\.css$/,{
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',{ from: { glob: '**/*.png',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,`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'
],webpackConfig: config,snapshotInDocker,skipSnapshottools,useLibs
})
);
}
if (!production && hmr) {
config.plugins.push(new webpack.HotModuleReplacementPlugin());
}
return config;
};
谢谢。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。