Skip to content

Proposal: Provide a way to add externals to webpack config #2141

Closed

Description

@MrChoclate

The issue is that if I use global script via app[0].scripts I cannot use it again in my .ts files.

Example: if I have:

      "scripts": [
        "../node_modules/jquery/dist/jquery.js",
        "../node_modules/moment/moment.js",
        "../node_modules/fullcalendar/dist/fullcalendar.min.js"
      ],

I cannot do: import * as moment from 'moment';. If I do so, moment will become an empty object. Of course, I can use it without importing it since it is global BUT other libs that depends on moment (angular2-moment in my case) will do import * as moment from 'moment';, they will get an empty object and their code will break.
Then I cannot use this libs. (I think #1974 is related)

I cannot remove moment from scripts since I have other global scripts that depend on it (fullcalendar). Maybe there is a way to make all this scripts work without apps[0].scripts but I have not found it.

My solution is to use webpack externals https://webpack.github.io/docs/library-and-externals.html

If I add

externals: {
      'moment': 'moment'
    },

to webpack-build-common.ts it is working.

I can provide a PR adding externals from apps[0].externals to the webpack config. Is it the right solution?

Activity

  1. clydin commented on Sep 19, 2016

    @clydin
    Member

    Something to experiment with (that does not require modification of the CLI itself) is to add a vendor.ts file to the first position of scripts in angular-cli.json and remove the jquery and moment lines.

    Potential contents of vendor.ts:

    import * as moment from 'moment';
    import * as jquery from 'jquery';
    
    window['moment'] = moment;
    window['jQuery'] = window['$'] = jquery;
    
  2. isaackehle commented on Oct 4, 2016

    @isaackehle

    I am interested in this feature as well, for this exact reason. Is this in process?

  3. alejoar commented on Oct 5, 2016

    @alejoar

    @pgkehle the solution provided by @clydin works perfectly, although I am interested on this working out of the box too.

  4. isaackehle commented on Oct 5, 2016

    @isaackehle

    @alejoar I am working through this, but getting a lot of errors related now to jQuery not found, as my app uses bootstrap v4 and other modules. Curious if there is a working example.

    bootstrap.js:8 Uncaught Error: Bootstrap's JavaScript requires jQuery
    
  5. self-assigned this
    on Oct 9, 2016
  6. filipesilva commented on Oct 9, 2016

    @filipesilva
    Contributor

    @pgkehle you can already use bootstrap4, see https://github.com/angular/angular-cli#global-library-installation. The problem shown in this issue is specific to how dependencies used in both scripts and inside your app interact.

  7. MrChoclate commented on Oct 30, 2016

    @MrChoclate
    Author

    @clydin Your fix does not seem to work for me in Firefox 49 but works in Chrome 53.
    I ran into an issue with scrolltofixed plugin (unhelpful error message). (Works with my PR)

    But I had to use $('#calendar').fullCalendar in ngAfterViewChecked and not after ngAfterViewInit (for Firefox and with my PR). So maybe I misused life cycle hooks with the scrolltofixed plugin.

    Anyway, either your fix does not work with Firefox or lifecycle hooks works differently between Chrome and Firefox. Did you test your fix with Firefox? When do you use jQuery plugins? ngAfterViewInit or ngAfterViewChecked?

  8. maxailloud commented on Nov 15, 2016

    @maxailloud

    I have the exact same issue with almost (not the same calendar package) the same case with moment.
    Definitely something weird going on here.

  9. added
    P1Impacts a large percentage of users; if a workaround exists it is partial or overly painful
    and removed
    needs: investigationRequires some digging to determine if action is needed
    on Nov 21, 2016
  10. added this to the milestone on Nov 21, 2016
  11. added a commit that references this issue on Jan 1, 2017
    ef0d4af
  12. filipesilva commented on Jan 1, 2017

    @filipesilva
    Contributor

    So #3814 fixes this issue, but not by adding externals.

    Rather, it fixes a bug that forced files listed as scripts to always be loaded as a string via script-loader, making them useless for imports.

  13. filipesilva commented on Jan 1, 2017

    @filipesilva
    Contributor

    I'd like to note that, since this is NOT the externals functionality, if you want to use the global instance you will need to still declare libInstance: any (or some other type) and never import directly.

    I'd prefer to not add externals because it forces people to figure out how some libs work and what they export. For some libs that's really hard to tell.

    I think it's overall preferable to just have feature parity with script tags which is a much simpler concept to understand, explain and use.

  14. added a commit that references this issue on Jan 4, 2017
    acda842
  15. gregvis commented on Jan 4, 2017

    @gregvis

    I still require externals for using Angular 2 with Electron.

    For example, i'm using an npm library called 'drivelist' which calls a node 'child_process'. The only way I could get this to work with ng-serve is to make 'drivelist' external and have Electron load the module.

    For ng serve, i included the external like this to work:

    externals: {
    'drivelist': 'commonjs '+ path.resolve(projectRoot, 'node_modules', 'drivelist'),
    'electron': 'commonjs electron'

        }
    

    Then in Electron, i'm just loading the ng serve url:

    win = new BrowserWindow({width: 800, height: 600})
    win.loadURL('http://localhost:4200');

  16. added 2 commits that reference this issue on Jan 11, 2017
    c95bbde
    0f0bbc9
  17. thejewdude commented on Jan 13, 2017

    @thejewdude

    I have an issue that is kind of related.
    My setup:
    My app uses Fullcalendar which depends on momentjs to be in global scope. I am also using moment throughout my app. Fullcalendar is added with angular-cli.json, but due to this issue I added moment to index.html with a script tag.
    The issue is that ng test throws an exception due to moment not being defined. I see that the test runner is loading all the scripts defined in the angular-cli.json. Moment is not in loaded to global scope because it seems that the test runner is ignoring the index.html and any script tags defined there won't be available in the testing environment.
    This issue only cropped up in newer versions of the cli (maybe as early as beta.24). Does this warrant a new issue?

  18. added a commit that references this issue on Jan 20, 2017
    a2ea05e
  19. added a commit that references this issue on Feb 9, 2017
    b103e50
  20. angular-automatic-lock-bot commented on Sep 6, 2019

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  21. locked and limited conversation to collaborators on Sep 6, 2019
  22. added a commit that references this issue on May 29, 2026
    1331bb0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P1Impacts a large percentage of users; if a workaround exists it is partial or overly painfultype: bug/fix

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions