NativeScript / nativescript-dev-webpack

A package to help with webpacking NativeScript apps.
Apache License 2.0
97 stars 49 forks source link

Customize appComponents in Webpack 5 #1157

Closed Macarthurval closed 3 years ago

Macarthurval commented 3 years ago

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):

package.json

{
  "name": "@nativescript/template-drawer-navigation-ts",
  "main": "src/main.ts",
  "displayName": "Navigation Drawer",
  "templateType": "App template",
  "version": "8.0.5",
  "description": "NativeScript Application",
  "author": "NativeScript Team <oss@nativescript.org>",
  "license": "SEE LICENSE IN <your-license-filename>",
  "publishConfig": {
    "access": "public"
  },
  "files": [
    "App_Resources",
    "hooks",
    "src",
    "tools",
    "!tools/assets",
    ".editorconfig",
    "references.d.ts",
    "tsconfig.json"
  ],
  "keywords": [
    "nstudio",
    "nativescript",
    "mobile",
    "{N}",
    "tns",
    "template",
    "drawer",
    "navigation",
    "category-general"
  ],
  "repository": "<fill-your-repository-here>",
  "homepage": "https://github.com/NativeScript/nativescript-app-templates",
  "bugs": {
    "url": "https://github.com/NativeScript/NativeScript/issues"
  },
  "dependencies": {
    "@nativescript/background-http": "^5.0.2",
    "@nativescript/core": "~8.0.0",
    "@nativescript/datetimepicker": "^2.1.3",
    "@nativescript/firebase": "^11.1.3",
    "@nativescript/imagepicker": "^1.0.4",
    "@nativescript/local-notifications": "^5.0.3",
    "@nativescript/localize": "^5.0.4",
    "@nativescript/secure-storage": "^3.0.0",
    "@nativescript/social-share": "^2.0.4",
    "@nativescript/theme": "~3.0.1",
    "@nestjs/config": "^0.6.3",
    "nativescript-apple-sign-in": "^2.0.0",
    "nativescript-audio": "^6.2.4",
    "nativescript-call": "^0.2.0",
    "nativescript-clipboard": "^2.1.1",
    "nativescript-imagecropper": "^4.0.1",
    "nativescript-insomnia": "^2.0.0",
    "nativescript-iqkeyboardmanager": "^1.5.1",
    "nativescript-plugin-statusbar": "^1.0.19",
    "nativescript-ui-sidedrawer": "~9.0.3",
    "nativescript-videoplayer": "^5.0.1",
    "rxjs": "~6.6.0"
  },
  "devDependencies": {
    "@nativescript/android": "8.0.0",
    "@nativescript/ios": "8.0.0",
    "@nativescript/types": "~8.0.0",
    "@nativescript/webpack": "beta",
    "typescript": "~4.0.0"
  },
  "private": "true",
  "readme": "NativeScript Application"
}

webpack.config.ts

const webpack = require("@nativescript/webpack");
const { resolve } = require("path")

module.exports = env => {

    env.appComponents = env.appComponents || [];
    env.appComponents.push(...[
        "@nativescript/core/ui/frame",
        "@nativescript/core/ui/frame/activity"],
        resolve(__dirname, "src/activity.android"),
    )
    webpack.init(env);

  // Learn how to customize:
  // https://docs.nativescript.org/webpack
  webpack.Utils.addCopyRule("**/*.mp3");
  webpack.Utils.addCopyRule("**/*.mp4");
  webpack.Utils.addCopyRule("**/*.png");

  return webpack.resolveConfig();
};

Describe the bug Hello, I'm getting a com.tns.system.classes.loading.LookedUpClassNotFound error at application startup, after Webpack compilation is completed. I'm trying to use a custom activity on my app, and I suspect that is my webpack.config.js what is wrong, because I couldn't find any example for the new Nativescript 8 and Webpack 5 about how to customize the appComponents option.

To Reproduce

activity.android.ts

import {setActivityCallbacks, AndroidActivityCallbacks} from "@nativescript/core/ui/frame";
import { VolumeService } from "./classes/volume-service";

@NativeClass()
@JavaProxy("com.arturojs.less.MainActivity")
class MainActivity extends androidx.appcompat.app.AppCompatActivity {
    public isNativeScriptActivity;
    private _callbacks: AndroidActivityCallbacks;

    public onCreate(savedInstanceState: android.os.Bundle): void {
        this.isNativeScriptActivity = true;
        if (!this._callbacks) {
            setActivityCallbacks(this);
        }

        this._callbacks.onCreate(this, savedInstanceState, this.getIntent(), super.onCreate);
    }

    public onSaveInstanceState(outState: android.os.Bundle): void {
        this._callbacks.onSaveInstanceState(this, outState, super.onSaveInstanceState);
    }

    public onStart(): void {
        this._callbacks.onStart(this, super.onStart);
    }

    public onStop(): void {
        this._callbacks.onStop(this, super.onStop);
    }

    public onDestroy(): void {
        this._callbacks.onDestroy(this, super.onDestroy);
    }

    public onBackPressed(): void {
        this._callbacks.onBackPressed(this, super.onBackPressed);
    }

    public onRequestPermissionsResult(requestCode: number, permissions: Array<string>, grantResults: Array<number>): void {
        this._callbacks.onRequestPermissionsResult(this, requestCode, permissions, grantResults, undefined /*TODO: Enable if needed*/);
    }

    public onActivityResult(requestCode: number, resultCode: number, data: android.content.Intent): void {
        this._callbacks.onActivityResult(this, requestCode, resultCode, data, super.onActivityResult);
    }

    public dispatchKeyEvent(event) {
        // Which direction did the key move (up/down)
        let action = event.getAction();

        // What keywas pressed
        let keyCode = event.getKeyCode();

        switch (keyCode) {
            case android.view.KeyEvent.KEYCODE_VOLUME_UP:
                // Check your event code (KeyEvent.ACTION_DOWN, KeyEvent.ACTION_UP etc)
                console.log("KEYCODE_VOLUME_UP");
                VolumeService.getInstance().selfUpdate()
                return true;
            case android.view.KeyEvent.KEYCODE_VOLUME_DOWN:
                    // Check your event code (KeyEvent.ACTION_DOWN, KeyEvent.ACTION_UP etc)
                console.log("KEYCODE_VOLUME_DOWN");
                VolumeService.getInstance().selfUpdate()
                return true;
            default:
                // Let the system do what it wanted to do
                return super.dispatchKeyEvent(event);
        }
    }
}

AndroidManifest.xml

<activity
            android:name="com.arturojs.less.MainActivity"
            android:label="@string/title_activity_kimera"
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|locale|uiMode"
            android:theme="@style/LaunchScreenTheme">

webpack.config.js

const webpack = require("@nativescript/webpack");
const { resolve } = require("path")

module.exports = env => {

    env.appComponents = env.appComponents || [];
    env.appComponents.push(...[
        "@nativescript/core/ui/frame",
        "@nativescript/core/ui/frame/activity"],
        resolve(__dirname, "src/activity.android"),
    )
    webpack.init(env);

  // Learn how to customize:
  // https://docs.nativescript.org/webpack
  webpack.Utils.addCopyRule("**/*.mp3");
  webpack.Utils.addCopyRule("**/*.mp4");
  webpack.Utils.addCopyRule("**/*.png");

  return webpack.resolveConfig();
};

Expected behavior App startup without error

Sample project

Additional context

edusperoni commented 3 years ago

You don't need to add UI/frame and activity to your app components. Also, I believe you have to rebuild the app (try a ns clean) so the class is picked up by the sbg

Macarthurval commented 3 years ago

@edusperoni you're the man, a ns clean did the trick for me, big thanks!