Issue Checklist
Tell us about the problem
I am trying to add webpack support to an existing application, by following these instructions. The app gets built correctly, however upon reaching a certain view I get the before mentioned error:
System.err: Caused by: com.tns.NativeScriptException:
System.err: Calling js method onStart failed
System.err: Error: Building UI from XML. @file:///app/views/myapp/dashboard/dashboard.xml:38:11
System.err: > Module 'ui/layouts/wrap-layout' not found for element 'WrapLayout'.
System.err: > com.tns.NativeScriptException: Failed to find module: "ui/layouts/wrap-layout", relative to: app/tns_modules/
System.err: com.tns.Module.resolvePathHelper(Module.java:146)
It's worth mentioning that said view makes use of the nativescript-ui-sidedrawer, and the nativescript-i18n plugins and that the problematic WrapLayout is inside the sd:RadSideDrawer.mainContent element, it goes like this:
<Page
xmlns:sd="nativescript-ui-sidedrawer"
xmlns:shared="shared/xml-controls"
xmlns="http://schemas.nativescript.org/tns.xsd"
navigatingTo="navigatingTo" class="page">
<Page.actionBar>
...
</Page.actionBar>
<sd:RadSideDrawer id="sideDrawer">
<sd:RadSideDrawer.drawerContent>
<shared:sidedrawer/> <!-- This is some custom element I use to avoid copy-pasting the contents of the drawer -->
</sd:RadSideDrawer.drawerContent>
<sd:RadSideDrawer.mainContent>
<StackLayout>
<StackLayout>
...
</StackLayout>
<ScrollView>
<WrapLayout>
...
</WrapLayout>
</ScrollView>
</StackLayout>
</sd:RadSideDrawer.mainContent>
</sd:RadSideDrawer>
</Page>
The problem seems to be solved by also registering the ui/layouts/wrap-layout module in bundle-config:
global.registerModule("ui/layouts/wrap-layout", () => require("tns-core-modules/ui/layouts/wrap-layout"));
This will let me see the view but nothing seems to work, the sidedrawer won't show up upon tapping the designated toggle button and the text on all elements (handled by the i18n plugin) is missing.
Local environment
- Platform Linux
- Node version 9.3.0
- NativeScript CLI version 3.4.3
Project data
- [Android] Platform you are building the app for
- Node dependencies:
"dependencies": {
"nativescript-barcodescanner": "^2.7.6",
"nativescript-cardview": "^2.0.5",
"nativescript-carousel": "^3.1.1",
"nativescript-fancyalert": "^1.2.0",
"nativescript-i18n": "^0.2.4",
"nativescript-imagepicker": "^5.0.2",
"nativescript-photoviewer": "^1.4.0",
"nativescript-plugin-firebase": "^5.1.8",
"nativescript-theme-core": "^1.0.4",
"nativescript-toast": "^1.4.6",
"nativescript-ui-sidedrawer": "^3.5.2",
"nativescript-videoplayer": "^3.1.0",
"tns-core-modules": "^3.4.1",
"tslint": "^5.9.1"
},
"devDependencies": {
"awesome-typescript-loader": "~3.1.3",
"babel-traverse": "6.26.0",
"babel-types": "6.26.0",
"babylon": "6.18.0",
"copy-webpack-plugin": "~4.3.0",
"css-loader": "~0.28.7",
"extract-text-webpack-plugin": "~3.0.2",
"lazy": "1.0.11",
"nativescript-dev-typescript": "^0.6.0",
"nativescript-dev-webpack": "^0.9.2",
"nativescript-worker-loader": "~0.8.1",
"raw-loader": "~0.5.1",
"resolve-url-loader": "~2.2.1",
"typescript": "~2.4.2",
"uglifyjs-webpack-plugin": "~1.1.6",
"webpack": "~3.10.0",
"webpack-bundle-analyzer": "^2.9.1",
"webpack-sources": "~1.1.0"
}
const { resolve, join } = require("path");
const webpack = require("webpack");
const nsWebpack = require("nativescript-dev-webpack");
const nativescriptTarget = require("nativescript-dev-webpack/nativescript-target");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
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 platforms = ["ios", "android"];
const { snapshot, uglify, report } = env;
const config = {
context: resolve("./app"),
target: nativescriptTarget,
entry: {
bundle: `./${nsWebpack.getEntryModule()}`,
vendor: "./vendor"
},
output: {
pathinfo: true,
// Default destination inside platforms/<platform>/...
path: resolve(nsWebpack.getAppPath(platform)),
libraryTarget: "commonjs2",
filename: "[name].js",
},
resolve: {
extensions: [".ts", ".js", ".scss", ".css"],
// Resolve {N} system modules from tns-core-modules
modules: [
"node_modules/tns-core-modules",
"node_modules",
],
alias: {
'~': resolve("./app")
},
// don't resolve symlinks to symlinked modules
symlinks: false
},
resolveLoader: {
// don't resolve symlinks to symlinked loaders
symlinks: false
},
node: {
// Disable node shims that conflict with NativeScript
"http": false,
"timers": false,
"setImmediate": false,
"fs": "empty",
},
module: {
rules: [
{ test: /\.(html|xml)$/, use: "raw-loader" },
{
test: /\.css$/,
use: { loader: "css-loader", options: { minimize: false, url: false } }
},
{
test: /\.scss$/,
use: [
{ loader: "css-loader", options: { minimize: false, url: false } },
"sass-loader"
]
},
{ test: /\.ts$/, use: "awesome-typescript-loader" }
]
},
plugins: [
// Vendor libs go to the vendor.js chunk
new webpack.optimize.CommonsChunkPlugin({
name: ["vendor"],
}),
// Define useful constants like TNS_WEBPACK
new webpack.DefinePlugin({
"global.TNS_WEBPACK": "true",
}),
// Copy assets to out dir. Add your own globs as needed.
new CopyWebpackPlugin([
{ from: "App_Resources/**" },
{ from: "fonts/**" },
{ from: "**/*.jpg" },
{ from: "**/*.png" },
{ from: "**/*.xml" },
]),
// Generate a bundle starter script and activate it in package.json
new nsWebpack.GenerateBundleStarterPlugin([
"./vendor",
"./bundle",
]),
// Support for web workers since v3.2
new NativeScriptWorkerPlugin(),
new nsWebpack.PlatformFSPlugin({
platform,
platforms,
// ignore: ["App_Resources"]
}),
// 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: join(__dirname, "report", `report.html`),
statsFilename: join(__dirname, "report", `stats.json`),
}));
}
if (snapshot) {
config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({
chunk: "vendor",
projectRoot: __dirname,
webpackConfig: config,
targetArchs: ["arm", "arm64", "ia32"],
tnsJavaClassesOptions: { packages: ["tns-core-modules" ] },
useLibs: false
}));
}
if (uglify) {
config.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true }));
// Work around an Android issue by setting compress = false
const compress = platform !== "android";
config.plugins.push(new UglifyJsPlugin({
uglifyOptions: {
mangle: { reserved: nsWebpack.uglifyMangleExcludes },
compress,
}
}));
}
return config;
};
Issue Checklist
Tell us about the problem
I am trying to add webpack support to an existing application, by following these instructions. The app gets built correctly, however upon reaching a certain view I get the before mentioned error:
It's worth mentioning that said view makes use of the nativescript-ui-sidedrawer, and the nativescript-i18n plugins and that the problematic WrapLayout is inside the sd:RadSideDrawer.mainContent element, it goes like this:
<Page xmlns:sd="nativescript-ui-sidedrawer" xmlns:shared="shared/xml-controls" xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page"> <Page.actionBar> ... </Page.actionBar> <sd:RadSideDrawer id="sideDrawer"> <sd:RadSideDrawer.drawerContent> <shared:sidedrawer/> <!-- This is some custom element I use to avoid copy-pasting the contents of the drawer --> </sd:RadSideDrawer.drawerContent> <sd:RadSideDrawer.mainContent> <StackLayout> <StackLayout> ... </StackLayout> <ScrollView> <WrapLayout> ... </WrapLayout> </ScrollView> </StackLayout> </sd:RadSideDrawer.mainContent> </sd:RadSideDrawer> </Page>The problem seems to be solved by also registering the ui/layouts/wrap-layout module in bundle-config:
global.registerModule("ui/layouts/wrap-layout", () => require("tns-core-modules/ui/layouts/wrap-layout"));This will let me see the view but nothing seems to work, the sidedrawer won't show up upon tapping the designated toggle button and the text on all elements (handled by the i18n plugin) is missing.
Local environment
Project data
"dependencies": { "nativescript-barcodescanner": "^2.7.6", "nativescript-cardview": "^2.0.5", "nativescript-carousel": "^3.1.1", "nativescript-fancyalert": "^1.2.0", "nativescript-i18n": "^0.2.4", "nativescript-imagepicker": "^5.0.2", "nativescript-photoviewer": "^1.4.0", "nativescript-plugin-firebase": "^5.1.8", "nativescript-theme-core": "^1.0.4", "nativescript-toast": "^1.4.6", "nativescript-ui-sidedrawer": "^3.5.2", "nativescript-videoplayer": "^3.1.0", "tns-core-modules": "^3.4.1", "tslint": "^5.9.1" }, "devDependencies": { "awesome-typescript-loader": "~3.1.3", "babel-traverse": "6.26.0", "babel-types": "6.26.0", "babylon": "6.18.0", "copy-webpack-plugin": "~4.3.0", "css-loader": "~0.28.7", "extract-text-webpack-plugin": "~3.0.2", "lazy": "1.0.11", "nativescript-dev-typescript": "^0.6.0", "nativescript-dev-webpack": "^0.9.2", "nativescript-worker-loader": "~0.8.1", "raw-loader": "~0.5.1", "resolve-url-loader": "~2.2.1", "typescript": "~2.4.2", "uglifyjs-webpack-plugin": "~1.1.6", "webpack": "~3.10.0", "webpack-bundle-analyzer": "^2.9.1", "webpack-sources": "~1.1.0" }const { resolve, join } = require("path"); const webpack = require("webpack"); const nsWebpack = require("nativescript-dev-webpack"); const nativescriptTarget = require("nativescript-dev-webpack/nativescript-target"); const CopyWebpackPlugin = require("copy-webpack-plugin"); const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer"); const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin"); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); 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 platforms = ["ios", "android"]; const { snapshot, uglify, report } = env; const config = { context: resolve("./app"), target: nativescriptTarget, entry: { bundle: `./${nsWebpack.getEntryModule()}`, vendor: "./vendor" }, output: { pathinfo: true, // Default destination inside platforms/<platform>/... path: resolve(nsWebpack.getAppPath(platform)), libraryTarget: "commonjs2", filename: "[name].js", }, resolve: { extensions: [".ts", ".js", ".scss", ".css"], // Resolve {N} system modules from tns-core-modules modules: [ "node_modules/tns-core-modules", "node_modules", ], alias: { '~': resolve("./app") }, // don't resolve symlinks to symlinked modules symlinks: false }, resolveLoader: { // don't resolve symlinks to symlinked loaders symlinks: false }, node: { // Disable node shims that conflict with NativeScript "http": false, "timers": false, "setImmediate": false, "fs": "empty", }, module: { rules: [ { test: /\.(html|xml)$/, use: "raw-loader" }, { test: /\.css$/, use: { loader: "css-loader", options: { minimize: false, url: false } } }, { test: /\.scss$/, use: [ { loader: "css-loader", options: { minimize: false, url: false } }, "sass-loader" ] }, { test: /\.ts$/, use: "awesome-typescript-loader" } ] }, plugins: [ // Vendor libs go to the vendor.js chunk new webpack.optimize.CommonsChunkPlugin({ name: ["vendor"], }), // Define useful constants like TNS_WEBPACK new webpack.DefinePlugin({ "global.TNS_WEBPACK": "true", }), // Copy assets to out dir. Add your own globs as needed. new CopyWebpackPlugin([ { from: "App_Resources/**" }, { from: "fonts/**" }, { from: "**/*.jpg" }, { from: "**/*.png" }, { from: "**/*.xml" }, ]), // Generate a bundle starter script and activate it in package.json new nsWebpack.GenerateBundleStarterPlugin([ "./vendor", "./bundle", ]), // Support for web workers since v3.2 new NativeScriptWorkerPlugin(), new nsWebpack.PlatformFSPlugin({ platform, platforms, // ignore: ["App_Resources"] }), // 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: join(__dirname, "report", `report.html`), statsFilename: join(__dirname, "report", `stats.json`), })); } if (snapshot) { config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({ chunk: "vendor", projectRoot: __dirname, webpackConfig: config, targetArchs: ["arm", "arm64", "ia32"], tnsJavaClassesOptions: { packages: ["tns-core-modules" ] }, useLibs: false })); } if (uglify) { config.plugins.push(new webpack.LoaderOptionsPlugin({ minimize: true })); // Work around an Android issue by setting compress = false const compress = platform !== "android"; config.plugins.push(new UglifyJsPlugin({ uglifyOptions: { mangle: { reserved: nsWebpack.uglifyMangleExcludes }, compress, } })); } return config; };