adamrdrew / VueZen

VueZen brings the power and simplicity of the VueJS stack to Tizen
8 stars 0 forks source link

Can not compile with non-top level components #19

Open JWBWork opened 4 years ago

JWBWork commented 4 years ago

After generating a component where the top-level value is false I get the following error.

C:\Users\jacob\TizenWorkspace\VueSets>grunt compile
Running "compile" task
Warning: Cannot read property 'path' of undefined Use --force to continue.

Aborted due to warnings.

I managed to identify the source of this error to this function from tasks/compile.js:

this.defaultRouteExists = function () {
       return !!this.routes.filter((r) => r.path == "*").length;
}

I adressed this error with the following tweak:

this.defaultRouteExists = function () {
       var definedRoutes = this.routes.filter((r) => typeof r != "undefined");
       return !!definedRoutes.filter((r) => r.path == "*").length;
}

But attempts to compile after this complete successfully, but debugging shows the following error at vue-router.min.js:6

Uncaught TypeError: Cannot read property 'path' of undefined
    at L (file:///lib/vue/vue-router.min.js:6:7289)
    at file:///lib/vue/vue-router.min.js:6:7128
    at Array.forEach (native)
    at q (file:///lib/vue/vue-router.min.js:6:7108)
    at M (file:///lib/vue/vue-router.min.js:6:10000)
    at new Zt (file:///lib/vue/vue-router.min.js:6:21437)
    at file:///js/vue_app.js:32:24

It seems like the project can't use components within components as a result. Can anyone assist?

JWBWork commented 4 years ago

I've managed to correct the error thrown above with the following change to vue_app.js at lines 29 to 33.

// VueRouter page to route manager
// Allows for multi-page apps with easy view transitions and back button integration
// See https://router.vuejs.org/en/ for more information
__VueZenRoutes = __VueZenRoutes.filter(route => typeof route != "undefined");
const __VueZenRouter = new VueRouter({routes: __VueZenRoutes});

This compiles and does not throw the above error at runtime. However, I still can't manage to get the components to load properly within other components. Inspecting the HTML shows that the component, name like "SampleName" is in the template as <SampleName/> and is rendering as <samplename></samplename>.

JWBWork commented 4 years ago

So I've now realized that the issue has to do with my attempt to import the component inside the other component. Any component that uses require or import within the script tag throws an error when trying to execute eval("("+this.tags.script.value+")") within compile.js

Currently looking into how I can import these components safely or register them globally.

JWBWork commented 4 years ago

So I've managed a workaround to get "functional" imports of non-top-level components.

After compiling with the grunt script I go into the resulting "compiled.js". There I list the component object within the components: {} attribute object of the component I wish to import the sub-component into.

Basically before compiling my parent component has the following property:

components: {
        //SubComponent
},

Then after compiling I manually place the SubComponent reference within the components tag of the resulting const created by the compile.js script.

The result is that the child component renders! But there is the following exception, I'm not sure what consequences there are as of yet...

TypeError: n[r].call is not a function
    at At (vue.min.js:6)
    at Object.insert (vue.min.js:6)
    at x (vue.min.js:6)
    at _e.r.nodeOps [as __patch__] (vue.min.js:6)
    at _e.t._update (vue.min.js:6)
    at _e.r (vue.min.js:6)
    at _o.get (vue.min.js:6)
    at new _o (vue.min.js:6)
    at bt (vue.min.js:6)
    at _e.$mount (vue.min.js:6)
k @ vue.min.js:6
JWBWork commented 4 years ago

By importing components like so within a component I can compile without errors and do not need to edit the resulting 'compiled.js' file

components: {
     ExerciseList: () => import('./ExerciseList.vue')
},

However this throws the following error in runtime Uncaught SyntaxError: Unexpected token import

JWBWork commented 4 years ago

When the sub-component is imported like so the app will compile without errors and throws no exceptions during runtime.

components: {
    ExerciseList: () => ExerciseList
},

but the sub componenet does not render. Where the component should be there is onle this: <!---->

JWBWork commented 4 years ago

So I've augmented the compile.js script so that the component renders when compiling. I've done so by making it so I can list string values in the import statement that are then corrected to the component name by the compiler like so

Parent component importing child component:

components: {
            SubComponent: "vc-SubComponent",
        },

Within compile.js I augmented the compile method of the Component object like so:

this.compile = function () {
        var scriptObj       = eval("("+this.tags.script.value+")");
        scriptObj.template  = this.tags.template.valueStripped;
                return "const " + this.tags.name.value + " = " +
                    this.toSource(scriptObj).replace(/\s+/g, ' ').replace(/(\"vc-)(\w+)(\")/, "$2")
                    + ";\n";
}

This will compile without the script throwing errors and the component renders but there is the following error at runtime.

TypeError: e.call is not a function
    at He (vue.min.js:6)
    at Yt (vue.min.js:6)
    at Object.insert (vue.min.js:6)
    at k (vue.min.js:6)
    at wn.e.nodeOps [as __patch__] (vue.min.js:6)
    at wn.e._update (vue.min.js:6)
    at wn.r (vue.min.js:6)
    at fn.get (vue.min.js:6)
    at fn.run (vue.min.js:6)
    at un (vue.min.js:6)

I can't tell what the consequences of this are quite yet, I may have to try to use vue.js instead of vue.min.js in the future if I need to figure out what is going on here...

JWBWork commented 4 years ago

I've addressed the final error listed above and now the application is compiling and throws no exceptions at runtime! The final error was simply a misdefined 'mounted' attribute on my sub-component.

this:

mounted: {
      }

should have been this:

mounted: function () {
            this.$nextTick(function () {
                /* Code that will run only after the
                entire view has been rendered*/
            })
        }

I don't believe this.$nextTick is necessary, I just have it there for the future. I believe the definition of the mounted attribute as an object instead of a function was the result of the 'add.js' script. If so this will have to be adressed to avoid this exception in the future.