mendhak / angular-intro.js

AngularJS directives for intro.js
http://code.mendhak.com/angular-intro.js/
GNU Affero General Public License v3.0
503 stars 175 forks source link

Require intro.js #71

Open nlitwin opened 8 years ago

nlitwin commented 8 years ago

I'm using webpack and require to handle dependencies. I was finally able to get it working by changing angular-intro.js to the following:

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define(["angular", "intro.js"], factory);
    } else if (typeof exports === 'object') {
        module.exports = factory(require('angular'), require('intro'));
    } else {
        root.angularIntroJs = factory(root.angular, root.introJs);
    }
}.....

That is, with intro.js, instead of intro for the line define(["angular", "intro.js"], factory);

and requiring like so: require('angular-intro.js)

I also had to manually install intro.js via npm.

Is there a reason why the code is requiring intro as opposed to intro.js? How can I get it to work without augmenting the library code? Thank you for your time!

mendhak commented 8 years ago

It was done as part of an AMD Loading pull request, see here: https://github.com/mendhak/angular-intro.js/pull/49

You shouldn't have to manually install intro.js, if you did a bower install you'd get it along with.

nlitwin commented 8 years ago

I think the main issue was the name of intro.js. It was looking for a package named intro as opposed to intro.js, and couldn't find it.

banny310 commented 8 years ago

After change intro -> intro.js, loading using requirejs is dead.

jstroem commented 8 years ago

@banny310 can you make a quick demo showcasing this?

aadhoc commented 7 years ago

BTW, @banny310 was right. This doesn't work with requirejs. Today I tried to wireup angular-intro and intro into my requirejs SPA.

One solution for me was to change the amd section from "intro.js" to "intro". This worked for me after I took the normal step of configuring a path for the "intro" module id. Though this does force me to use the module id of "intro" (which is fine).

(function (root, factory) {
        if (typeof define === 'function' && define.amd) {
                define(["angular", "intro"], factory);
        } else if (typeof exports === 'object') {
                module.exports = factory(require('angular'), require('intro.js'));
        } else {
                root.angularIntroJs = factory(root.angular, root.introJs);
        }
}(this, function (angular, introJs) {

I traced deep into where you had define(["angular", "intro.js"], factory). It leads to a requirejs assumption that if the .js is on the end of the dependency name, it uses it verbatim as the url (the filename). Normally with requirejs, I would add the paths as I want, using the module id as a reference to the actual path (filename). For example {'intro': '../thirdparty/js/intro'} which lets me require 'intro' as the module id, and it uses my configured path ("../thirdparty/js/intro.js"). All that works great, but your define forces the module id to be "intro.js" and if I define a path with that module id (one with the ".js" extension) gets ignored.

This is in require.js (v 2.3.2, line 1637. Note the "ends with .js" comment):

                //If a colon is in the URL, it indicates a protocol is used and it is just
                //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
                //or ends with .js, then assume the user meant to use an url and not a module id.
                //The slash is important for protocol-less URLs as well as full paths.
                if (req.jsExtRegExp.test(moduleName)) {
                    //Just a plain path, not module name lookup, so just return it.
                    //Add extension if it is included. This is a bit wonky, only non-.js things pass
                    //an extension, this method probably needs to be reworked.
                    url = moduleName + (ext || '');
                } else {

I hope that's helpful. I haven't found another way around this in the few hours I've put in.

I don't know the etiquette around posting to a closed thread... but I hope you find this helpful. Thanks for the great module!

millerscout commented 7 years ago

I had it closed, because I thought it was resolved, I'll check your solution and get a environment using requirejs, thanks for the feedback :)

aadhoc commented 7 years ago

BTW, I copy the full & min files I need from node_modules into a "thirdparty" directory for deployment. Note that I modify the angular-intro JS files during the copy. So I'm happy with my hack, but I'm sure you'll find a real solution in the meantime :-)

    gulp.src([
        'node_modules/angular-intro.js/build/angular-intro*.js',
        'node_modules/angular-intro.js/src/angular-intro*.js',
    ])
        .pipe(replace(/define\(\["angular",\s*"intro\.js"\]/, 'define(["angular","intro"]'))
        .pipe(gulp.dest('thirdparty/js'));

Glad to provide the feedback. Thanks for the help.

millerscout commented 7 years ago

@aadhoc i'm currently making some tests on requirejs. now i fully understand what you were talking about.

i'm feeling strange change the name from "intro.js" to "intro". i feel more comfortable to "introJs" as it's the same as the object that we use, what do you think about it?

whatllb commented 7 years ago

Yes, module names are a bit inconsistent, with dashs, dots and even "js", ".js", "-js" suffixes. With my experience, authors forego the strange directory names and use filenames which make generally sense for the core project name.

These are examples of a few of the stranger directory names, but the filenames are still pretty standard:

The emergent standard across these and the modules without strange suffixes would be <module_plus_suffix>/src/<module>.js and <module_plus_suffix>/dist/<module>.min.js.

Since you are trying to decide on what to call the module you're including, you can choose anything, but you'll need to make it obvious to the developers since they will need to (or already have) included it in their requirejs "paths". I currently have mine defined as 'intro', but you can call yours whatever you want.

In the end it definitely doesn't matter, but don't include the dot.

millerscout commented 7 years ago

Hello!

i did make a beta version on > https://github.com/mendhak/angular-intro.js/releases/tag/v4.0.0-beta

changing the name of the module.

hope this helps 😄

avilao commented 7 years ago

Hi!

Is it gonna be on npm soon?

Thanks

Arti3DPlayer commented 6 years ago

+1