Load JS script on component level (not at startup)

2020-02-17 01:42发布

问题:

I have lots of JS files in my project. I want to load them when particular module or component load not when the app start.

How to do this?

Currently, I am loading them in index.html. The other way is to add them in angular-cli.json. But both ways will load the JS files at the startup. However, I need them to to load when the particular page or module runs.

回答1:

Just write a normal script loader :

   public loadScript() {
            let body = <HTMLDivElement> document.body;
            let script = document.createElement('script');
            script.innerHTML = '';
            script.src = 'url';
            script.async = true;
            script.defer = true;
            body.appendChild(script);
    }

and then call it where ever you want :

export class MyComponent{

    ngOnInit(){
        this.loadScript();

    }

}

But if those files are Typescript files, you can lazy load them as well in a numerous ways:

1- Using the default module level lazy loading

2- Using webpack's require

3- Using SystemJs module loader



回答2:

I have already given answer of this question but some how not able to mark as duplicate.

Please check this link : https://stackoverflow.com/a/44276683/6606630

where you can find how to load the external javascript at runtime at component level.

You have to create script element on the fly and then append it in DOM.

In that loadScript function i have just check existence of single js, if you have multiple js then you have to make some changes in logic.

Still if you have any query let me know, i will help you



回答3:

You can achieve this with the lazy loading feature of RouterModule.

Configure your app.module.ts like the following. The loadChildren-property must point to the destination of the module and after the hash must be the name of the module.

const routes: Routes = [
    {
        path: 'landing-page',
        loadChildren: './landing-page/landing-page.module#LandingPageModule'
    },
    {
        path: 'another-page',
        loadChildren: './another-page/another-page.module#AnotherPageModule'
    }
];

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    RouterModule.forRoot(routes),
    ...
  ],
  providers: [ ... ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Place the router-outlet inside of your html if not already done:

<router-outlet></router-outlet>

Then configure your page-modules like this:

const routes: Routes = [
  { path: '', component: LandingPageComponent },
  ...
];

@NgModule({
  imports: [
    RouterModule.forChild(routes),
    ...
  ],
  declarations: [ ... ],
  providers: [ ... ]
})
export class LandingPageModule { }

This produces a chunk for each module. In my project, it looks like this:

And when I open my site, i only the requred chunks for the current page will be loaded:



回答4:

Find a .angular-cli.json file and find a scripts array then add Your js scripts; Like this:

<root-directory> > .angular-cli.json > 
"scripts": [
  "../node_modules/tinymce/tinymce.js",
  "../node_modules/tinymce/themes/modern/theme.js",
]

OR you can use Lazy Loading...