preface

When I was browsing the forum today, I saw a friend ask Cocoscreator if they can use NPM package.

Post: Can NPM package be installed in coCOS Creator project?

I was thinking how could it not be?

So I click to see the big guy’s answer, and I read an article about AssetBundle written by the big guy

Creator | Asset Bundle full resolution

NPM packages are called into the main bundle and cannot be referenced in the package

This sentence made me think that all EasyGameFramework libraries are installed and used as NPM packages.

Wouldn’t it be annoying if you couldn’t subcontract references?

I did a test with the EGF-CCC-Full project and found that the preview worked, but the build didn’t, and the bundle was loaded with an error.

Later I tried to mount to the global, it can run normally, but the coding experience decreased a hundred times, the process is tedious.

I can’t take it anymore

There was a problem with the NPM package: it was not supported to reference NPM packages outside of the project folder, and the editor editor and build reported errors (but the preview did not). I have fixed that problem: Cocoscreator2.4.2/2.4.3 could not compile NPM modules that referenced outside the project folder

So I think the two questions should be about the same.

ABundle support reference NPM package today!!

@ Engine group

Is the question important?

I think it’s important!

Although it is possible to mount the NPM package to the global, then the script in the subcontract, to the global access.

But it’s not safe. The console is also accessible.

And most of all, it’s weird, you know? The coding experience is so bad.

The EasyGameFramework is all about making coding easier and more fun.

So today I let ABundle support reference NPM package!! ABundle support reference NPM package today!! Make EasyGameFramework seamless for subcontracting

Recurring problems

The flag is up, which means I’ve solved it. Ha ha ha ha ha. It can’t fall

Let’s just reproduce the problem and see what’s going on.

You can’t see the problem until you build, so build a wave first, which I tested using EGF-CCC-full.

Github.com/AILHC/EasyG…

You can clone it

Let me tell you a little bit about my test logic

  1. Load the abtest package: test/display-ctrl/abtest, and then inject the ABTestModule from this package into the module manager

2. Use the logic of the ABtest module to display the interface in abTest3. ABTestModule injects global components4. ABTestView inherits NodeCtrl of the @ailHC/dpctrl-CCC package

The look after running the build reported an error

@ailHC/dpctrL-CCC is not my package name, it was cut

Universal breakpoint debugging

  1. We will find that there are no script module objects in the subcontracted index.js, only two packages

2. Next step.

It then cuts the package name !!!! Just cut it?? !!!!!!!!! Why is that? NPM package name = NPM package name · There are special package names such as @babel/core, such as @ailhc/egf-coreCopy the code
  1. As we continue to trace, it goes into a require function, and then jumps over and finds that this index.js is in the main bundle

The cut name dpctrL-CCC could not be found in the main packageIn fact, the main package should have this package, but the key is wrong. I can actually find the @ailhc/dpctrl-ccc reference in main index.js by debugging it, but its key is converted to 4

Debugging summary

Through this series of tests, we can see

  • Index.js in main has the NPM package module, which can also be referenced
  • If the index. Js package refers to a script module outside the package, it will look up the main package
  • The logic of subcontracting to the main package to find modules does not take into account the case of the NPM package name
  • The beginning of index.js in both the main package and the subpackage looks like a template

After summing up, we went to try to solve the problem according to the results of our debugging

How to solve this problem?

The first step is to find the beginning of the index.js template

I found CocosDashboard resources.editors Creator 2.4.2 resources Static_prelude by going into the editor directory and searching for the text __require

(function e(t, n, r) {
    function s(o, u) {
        if(! n[o]) {if(! t[o]) {var b = o.split('/');
                b = b[b.length - 1];
                if(! t[b]) {var a = "function"= =typeof __require && __require;
                    if(! u && a)return a(b, !0);
                    if (i) return i(b, !0);
                    throw new Error("Cannot find module '" + o + "'");
                }
                o = b;
            }
            var f = n[o] = {
                exports: {}}; t[o][0].call(f.exports, function (e) {
                var n = t[o][1][e];
                return s(n || e);
            }, f, f.exports, e, t, n, r);
        }
        return n[o].exports;
    }
    var i = "function"= =typeof __require && __require;
    for (var o = 0; o < r.length; o++) s(r[o]);
    return s;
})

Copy the code

Much like aha!

Simply 🙄

Then I simply added a log and found that it was output after the rebuild, indicating that the change worked

Then, solve the logic that cuts out my NPM package name

Determine the type of path first, and then decide whether to cut

var b = o;
if (o.includes(". /")) {
// Internal code
b = o.split("/");
b = b[b.length - 1];
} else {
	/ / NPM package code
}

Copy the code

Finally, the mapping between the NPM package name and the module object has been converted in the main package

So?

The first time we reference it, we will check whether it is NPM package. If it is, we will record the package name as key. Next time, we will use the package name to look up

(function e(t, n, r) {
    function s(o, u, npmPkgName) {
        if(! n[o]) {if(! t[o]) {var b = o;
                if (o.includes(". /")) {
                    // Internal code
                    b = o.split("/");
                    b = b[b.length - 1];
                } else {
                    / / NPM package code
                }
                if(! t[b]) {var a = "function"= =typeof __require && __require;
                    if(! u && a)return a(b, !0);
                    if (i) return i(b, !0);
                    throw new Error("Cannot find module '" + o + "'");
                }
                o = b;
            }
            var f = n[o] = {
                exports: {}}; t[o][0].call(f.exports, function (e) {
                var n = t[o][1][e];
                // Check whether it is an NPM package
                return s(n || e, undefined, !e.includes(". /")? e :undefined);
            }, f, f.exports, e, t, n, r);
        }
        // Use the package name as the key to store the module reference
        if(npmPkgName && n[o] && ! n[npmPkgName]) { n[npmPkgName] = n[o]; }return n[o].exports;
    }
    var i = "function"= =typeof __require && __require;
    for (var o = 0; o < r.length; o++) s(r[o]);
    return s;
})

Copy the code

Rebuild, run, no error ~ done scatterflower ~

Important note

It’s done, but it has its limits

For example, if your main package doesn’t reference the NPM package, you can’t use it as a subpackage

The last

Welcome to pay attention to my public account, more content to continue to update

Public number search: play game development

Or scan code:

QQ group: 1103157878

Blog homepage: ailhc.github. IO /

The Denver nuggets: juejin. Cn/user / 306949…

github: github.com/AILHC