Ng-lazyload-image: Erreur de pré-rendu de la construction universelle angulaire

Créé le 8 janv. 2019  ·  23Commentaires  ·  Source: tjoskar/ng-lazyload-image

  • Je soumets un...

    • [x] rapport de bogue
    • [ ] demande de fonctionnalité
    • [ ] demande de soutien
  • Vous souhaitez demander une fonctionnalité ou signaler un bug ?
    Bug avec votre bibliothèque et la fonctionnalité de pré-rendu de la construction Angular Universal

  • Quel est le comportement actuel ?
    Lorsque vous exécutez la commande :
    npm run build:prerender

ça marche :
"generate:prerender": "cd dist && node prerender",

Puis échoue avec l'erreur :
```/node_modules/ng-lazyload-image/src/lazyload-image.module.js:1
(fonction (exports, require, module, __filename, __dirname) { import { NgModule } depuis '@angular/core';
^^^^^^

SyntaxError : importation de jetons inattendue
à createScript (vm.js:80:10)
à Object.runInThisContext (vm.js:139:10)
à Module._compile (module.js:617:28)
à Object.Module._extensions..js (module.js:664:10)
à Module.load (module.js:566:32)
à tryModuleLoad (module.js:506:12)
à Function.Module._load (module.js:498:3)
à Module.require (module.js:597:17)
au besoin (interne/module.js:11:18)
sur Object.ng-lazyload-image/src/lazyload-image.module (/dist/server/main.js:1350:18)


* **provide the steps to reproduce**
1) Duplicate the Angular Universal starter project from:
https://github.com/angular/universal-starter

2) Add your library, following install instructions:
https://github.com/tjoskar/ng-lazyload-image

3) Run the Angular build command to see the error:
```npm run build:prerender```

* **What is the expected behavior?**
No error, and to continue building.

* **What is the motivation / use case for changing the behavior?**
Otherwise your plugin cannot be used with Angular Universal, which means no static site generation :(

* **Please tell us about your environment:**
  - MacOS 10.13.6
  - node 8.9.1
  - ng-cli 6.0.0 and tested with 7.1.4
  - angular 6.0.0 and tested with 7.1.4
  - nguniversal 6.0.0 and tested with 7.0.2

* **Other information**

Looks like other people have had similar problems with Angular Universal and third-party libraries such as yours:
https://github.com/angular/angular-cli/issues/7200#issuecomment-329711848

They say the third-party libraries aren't being built correctly, which means Angular Universal fails:
https://github.com/angular/angular-cli/issues/7200#issuecomment-328991769

for example they suggest adding to your package.json
```"main": "./bundles/quickstart-lib.umd.js",
"module": "./quickstart-lib.es5.js",
"es2015": "./quickstart-lib.js",
"typings": "./quickstart-lib.d.ts",

Approche 1
Patchez la racine de votre plugin :
npm install @babel/cli @babel/core @babel/preset-env @babel/plugin-transform-modules-umd

Ajout d'un fichier .babelrc à la racine de votre dossier plugin :

{
  "plugins": [["@babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true }]],
  "presets": ["@babel/preset-env"]
}

Mise à jour de vos plugins package.json

"main": "./lib-umd/index.js",
"module": "./lib-es5/index.js",
"es2015": "./lib/index.js",
"typings": "./lib/index.d.ts",
"scripts": {
  "build:umd": "babel ./lib/*.js --out-dir ./lib-umd --plugins @babel/plugin-transform-modules-umd",
  "build:es5": "babel ./lib/*.js --out-dir ./lib-es5"
}

Ensuite, exécutez la compilation :
npm run build:es5 && npm run build:umd

Et en ajoutant à mon propre projet tsconfig.json

"compilerOptions": {
  "paths": { "@angular/*": ["../node_modules/@angular/*"] },
}

Mais toujours la même erreur avec Angular Universal :(

Approche 2
Utilisez les options de génération Typescript pour l'exemple de projet à l'adresse :
https://github.com/filipesilva/angular-quickstart-lib

bug

Commentaire le plus utile

Je rencontre le même problème en essayant de construire avec angulaire universel. @tjoskar avez-vous pensé à utiliser ng-packagr pour construire votre bibliothèque ? Vous pouvez créer et regrouper votre bibliothèque aux formats FESM2015, FESM5 et UMD.
Jetez un œil ici : https://github.com/ng-packagr/ng-packaged/blob/master/package.json#L11 (exemple de projet utilisant ng-packagr).

Tous les 23 commentaires

J'ai aussi eu la même erreur, j'ai installé angulaire universel

``` node_modules\ng-lazyload-image\index.js:1
(fonction (exports, require, module, __filename, __dirname) { import { LazyLoadImageDirective } depuis './src/lazyload-image.directive';
^^^^^^

SyntaxError : importation de jetons inattendue
à createScript (vm.js:80:10)
à Object.runInThisContext (vm.js:139:10)
à Module._compile (module.js:617:28)
à Object.Module._extensions..js (module.js:664:10)
à Module.load (module.js:566:32)
à tryModuleLoad (module.js:506:12)
à Function.Module._load (module.js:498:3)
à Module.require (module.js:597:17)
au besoin (interne/module.js:11:18)
à eval (webpack:///external_%22ng-lazyload-image%22?:1:18) ```

J'ai fini par écrire ma propre directive qui fonctionne avec Universal :

import { Directive, ElementRef, Inject, Input, OnInit, PLATFORM_ID} from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

@Directive({
  selector: '[appLazyLoadImage]'
})
export class LazyLoadImageDirective implements OnInit {
  @Input() srcLazy: string;

  constructor(
    private el: ElementRef,
    @Inject(PLATFORM_ID) private platformId: Object,
  ) { }

  ngOnInit() {
    // only run lazy image loading in the browser
    if (isPlatformBrowser(this.platformId)) {
      // if browser supports IntersectionObserver
      if ('IntersectionObserver' in window) {
        const lazyImageObserver = new IntersectionObserver((entries, observer) => {
          entries.forEach((entry) => {
            if (entry.isIntersecting) {
              entry.target.setAttribute('src', this.srcLazy);
              entry.target.classList.add('lazy-loaded');
              lazyImageObserver.unobserve(entry.target);
            }
          });
        });
        lazyImageObserver.observe(this.el.nativeElement);
      } else {
        // Otherwise replace image by default
        this.el.nativeElement.setAttribute('src', this.srcLazy);
      }
    }
  }

}

importez-le dans votre module :

import { LazyLoadImageDirective } from './lazy-load-image.directive';
...
@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [
    LazyLoadImageDirective
  ],
  exports: [
    CommonModule,
    LazyLoadImageDirective
  ]
})
...etc

et utiliser sur une image avec :
<img src="../assets/placeholder.jpg" srcLazy="../assets/myimage.jpg" alt="Example" appLazyLoadImage />

J'ai aussi eu la même erreur, j'ai installé angulaire universel

(function (exports, require, module, __filename, __dirname) { import { LazyLoadImageDirective } from './src/lazyload-image.directive';
                                                              ^^^^^^

SyntaxError: Unexpected token import
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:617:28)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at eval (webpack:///external_%22ng-lazyload-image%22?:1:18) ```

fonctionne avec ça

ajouté ceci sur la configuration webpack

externals: [ nodeExternals({ whitelist: [ /^ng-lazyload-image/, ] })

Je suppose que angular universal ne peut importer que des modules ComonJS et que ng-lazyload-image n'a que des modules ES comme cible, angular universal échoue.

Je suppose que nous devons configurer plusieurs cibles pour ng-lazyload-image , comme le décrit @kmturley . Mais cela signifierait également que le tremblement des arbres ne fonctionnera pas.

@xmasuku , pouvez-vous donner un exemple plus détaillé de votre configuration webpack ? Où utilisez-vous whitelist ?

@tjoskar J'ai utilisé mon build webpack personnalisé, je n'utilisais pas de cli angulaire

J'ai généré un projet cli et j'obtiens la même erreur

Bon je vais essayer d'y jeter un oeil ce soir

Je rencontre le même problème en essayant de construire avec angulaire universel. @tjoskar avez-vous pensé à utiliser ng-packagr pour construire votre bibliothèque ? Vous pouvez créer et regrouper votre bibliothèque aux formats FESM2015, FESM5 et UMD.
Jetez un œil ici : https://github.com/ng-packagr/ng-packaged/blob/master/package.json#L11 (exemple de projet utilisant ng-packagr).

// On dirait que c'est le problème commun pour universel, par exemple. https://github.com/angular/angular-cli/issues/7200
// J'ai cette configuration sur mon projet
// remplacez ceci : --- " compile:server " : " tsc -p server.tsconfig.json "
// avec ceci : --- " compile:server " : " node --max_old_space_size=3072 node_modules/webpack/bin/webpack.js --config webpack.server.config.js --progress --colors"

// puis créez webpack.server.config.js ajoutez le code ci-dessous :

const path = require('path');
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');

module.exports = {
  mode: 'none',
  entry: {
    // This is our Express server for Dynamic universal
    server: './server.ts'
  },
  target: 'node',
  resolve: { extensions: ['.ts', '.js'] },
  externals: [ nodeExternals({
    whitelist: [
        /^ng-lazyload-image/,
    ]
  }), /.*?webpack.*?/i ],
  optimization: {
    minimize: false
  },
  output: {
    // Puts the output at the root of the dist folder
    path: path.join(__dirname, 'dist'),
    filename: '[name].js'
  },
  module: {
    rules: [
      { test: /\.ts$/, loader: 'ts-loader' },
      {
        // Mark files inside `@angular/core` as using SystemJS style dynamic imports.
        // Removing this will cause deprecation warnings to appear.
        test: /(\\|\/)@angular(\\|\/)core(\\|\/).+\.js$/,
        parser: { system: true },
      },
    ]
  },
  plugins: [
    new webpack.ContextReplacementPlugin(
      // fixes WARNING Critical dependency: the request of a dependency is an expression
      /(.+)?angular(\\|\/)core(.+)?/,
      path.join(__dirname, 'src'), // location of your src
      {} // a map of your routes
    ),
    new webpack.ContextReplacementPlugin(
      // fixes WARNING Critical dependency: the request of a dependency is an expression
      /(.+)?express(\\|\/)(.+)?/,
      path.join(__dirname, 'src'),
      {}
    )
  ]
};

// mon serveur.ts

```
importer "zone.js/dist/zone-node" ;
importer {enableProdMode} depuis '@angular/core' ;
// Moteur express
importer {ngExpressEngine} depuis '@nguniversal/express-engine' ;
// Importation de la carte du module pour le chargement paresseux
importer {provideModuleMap} depuis '@nguniversal/module-map-ngfactory-loader' ;

importer * comme express de 'express';
import {join} depuis 'path' ;

// Rendu plus rapide du serveur avec le mode Prod (le mode dev n'est jamais nécessaire)
enableProdMode();

// Serveur express
const app = express();

const PORT = processus.env.PORT || 4000 ;
const DIST_FOLDER = join(process.cwd(), 'dist/browser');

// * REMARQUE :: laissez-le comme require() car ce fichier est construit dynamiquement à partir de webpack
const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist/server/main');

// Notre moteur express universel (trouvé @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
bootstrap : AppServerModuleNgFactory,
fournisseurs: [
fournirModuleMap(LAZY_MODULE_MAP)
]
}));

app.set('view engine', 'html');
app.set('vues', DIST_FOLDER);

// Exemple de points de terminaison d'API Express Rest
// app.get('/api/ *', (req, res) => { });// Servir les fichiers statiques de /browserapp.get(' .*', express.static(DIST_FOLDER, {
Âge max : '1y'
}));

// Tous les trajets réguliers utilisent le moteur Universal
app.get('*', (req, res) => {
res.render('index', { req });
});

// Démarrer le serveur Node
app.listen(PORT, () => {
console.log( Node Express server listening on http://localhost:${PORT} );
});

Pour l'instant, cela devrait fonctionner.

@tjoskar J'ai utilisé votre branche et cela semble résoudre le problème avec l'erreur de génération. Avez-vous un plan quand vous allez le fusionner et le publier ?

@Loutrinos , désolé pour le retard. Pouvez-vous s'il vous plaît essayer d'installer [email protected] (bêta) pour voir si cela résout le problème. Merci.

@tjoskar Je vois dans la version 5.1.0 que la structure est différente. C'est ok pour l'instant car il s'agit d'une version bêta.
Avec 5.1.0 Angular Universal ne casse plus :P

@Loutrinos ,

Je vois dans la version 5.1.0 que la structure est différente

Désolé, j'ai créé une nouvelle version ([email protected]) avec la même structure qu'avant. Mes semaines précédentes ont été assez mouvementées, mais maintenant je suis de retour aux affaires, alors faites-moi savoir comment cela fonctionne pour vous.

Après avoir installé la version 5.1.1 et j'obtiens cette erreur :
ReferenceError: IntersectionObserver is not defined

@agustintarifa À quoi ressemble votre fichier tsconfig.json ?

Je viens de créer ce dépôt : https://github.com/tjoskar/ng-lazyload-image-bugs/tree/master/370-universal-starter-compile et il semble fonctionner correctement. J'ai cloné https://github.com/angular/universal-starter , installé ng-lazyload-image (npm install [email protected]), ajouté une image , compilée avec npm run build:prerender et puis a démarré le serveur : node dist/server.js .

Merci pour la réponse @tjoskar
Cela fonctionne maintenant, j'ai changé mes modules.
Dans l'application.module, utilisez : LazyLoadImageModule.forRoot({}),
Et dans les autres modules : LazyLoadImageModule.forRoot({ preset: intersectionObserverPreset, }),

Le seul problème, l'offset ne fonctionne pas en haut pour voir la première image j'ai besoin de faire défiler 1px au moins puis l'autre se charge quand sont visibles, je veux charger les images 200px avant

Humm.. Dans mon exemple ci-dessus, je déclare seulement LazyLoadImageModule dans app.module et cela fonctionne bien et je ne peux pas vraiment reproduire l'erreur. Ce serait très utile si quelqu'un pouvait créer un petit dépôt pour reproduire l'erreur (ou fournir des instructions étape par étape).

@agustintarifa , Concernant le problème de décalage. Pouvez-vous créer un nouveau problème pour cela?

Salut, quand pouvons-nous nous attendre à ce que la version 5.1.1 soit stable et non bêta ? Parce que j'ai aussi ce problème avec SSR.

@vytautas-pranskunas-, je le publierai demain avec d'autres correctifs plus petits.

C'est super

Le lun. 1 avr. 2019, 21:17 Oskar Karlsson [email protected]
a écrit:

@vytautas-pranskunas- https://github.com/vytautas-pranskunas- , je le ferai
publiez-le demain avec d'autres correctifs plus petits.

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/tjoskar/ng-lazyload-image/issues/370#issuecomment-478709421 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/ADvMl18aKahOsS6vr4C4h4Tagwy2p4TNks5vclsrgaJpZM4Z0lGg
.

[email protected] est maintenant disponible. Faites-moi savoir que l'erreur persiste.

@tjoskar J'utilise 6.0.0 et le problème persiste ici.

// app.module.ts

LazyLoadImageModule.forRoot({
  preset: intersectionObserverPreset
}),

Et quand je démarre le serveur SSR, j'ai :

ReferenceError: IntersectionObserver is not defined

réf #396

Cette page vous a été utile?
0 / 5 - 0 notes