Ng-lazyload-image: Erro de pré-processamento da versão Angular Universal

Criado em 8 jan. 2019  ·  23Comentários  ·  Fonte: tjoskar/ng-lazyload-image

  • Estou enviando um ...

    • [x] relatório de bug
    • [] solicitação de recurso
    • [ ] solicitação de suporte
  • Você quer solicitar um recurso ou relatar um bug ?
    Bug com sua biblioteca e funcionalidade de pré-processamento de compilação Angular Universal

  • Qual é o comportamento atual?
    Ao executar o comando:
    npm run build:prerender

funciona:
"generate:prerender": "cd dist && node prerender",

Então falha com o erro:
`` `/node_modules/ng-lazyload-image/src/lazyload-image.module.js:1
(função (exporta, requer, módulo, __filename, __dirname) {import {NgModule} de '@ angular / core';
^^^^^^

SyntaxError: Importação de token inesperada
em createScript (vm.js: 80: 10)
em Object.runInThisContext (vm.js: 139: 10)
em Module._compile (module.js: 617: 28)
em Object.Module._extensions..js (module.js: 664: 10)
em Module.load (module.js: 566: 32)
em tryModuleLoad (module.js: 506: 12)
em Function.Module._load (module.js: 498: 3)
em Module.require (module.js: 597: 17)
em require (internal / module.js: 11: 18)
em 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",

Abordagem 1
Corrija a raiz do seu plugin:
npm install @babel/cli @babel/core @babel/preset-env @babel/plugin-transform-modules-umd

Adicionando um arquivo .babelrc na raiz da pasta do plug-in:

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

Atualizando seus plug-ins 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"
}

Em seguida, execute a compilação:
npm run build:es5 && npm run build:umd

E adicionando ao meu próprio projeto tsconfig.json

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

Mas ainda obtendo o mesmo erro com Angular Universal :(

Abordagem 2
Use as opções de construção do Typescript para o projeto de exemplo em:
https://github.com/filipesilva/angular-quickstart-lib

bug

Comentários muito úteis

Eu experimento o mesmo problema ao tentar construir com angular universal. @tjoskar , você já pensou em usar ng-packagr para construir sua biblioteca? Você pode construir e agrupar sua biblioteca nos formatos FESM2015, FESM5 e UMD.
Dê uma olhada aqui: https://github.com/ng-packagr/ng-packaged/blob/master/package.json#L11 (exemplo de projeto usando ng-packagr).

Todos 23 comentários

Também obtive o mesmo erro, tenho o angular universal instalado

`` `node_modules \ ng-lazyload-image \ index.js: 1
(função (exporta, requer, módulo, __filename, __dirname) {import {LazyLoadImageDirective} de './src/lazyload-image.directive';
^^^^^^

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

Acabei escrevendo minha própria diretiva que funciona com a 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);
      }
    }
  }

}

importe-o para o seu módulo:

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

e usar em uma imagem com:
<img src="../assets/placeholder.jpg" srcLazy="../assets/myimage.jpg" alt="Example" appLazyLoadImage />

Também obtive o mesmo erro, tenho o angular universal instalado

(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) ```

trabalha com isso

adicionado isto na configuração do webpack

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

Eu acho que angular universal só pode importar módulos ComonJS e como ng-lazyload-image só tem módulos ES como destino angular universal falha.

Acho que temos que configurar vários alvos para ng-lazyload-image , como @kmturley descreve. Mas isso também significaria que o movimento da árvore não funcionaria.

@xmasuku , você pode dar um exemplo mais detalhado da configuração do seu webpack? Onde você usa whitelist ?

@tjoskar Eu usei meu webpack customizado, não estava usando o angular cli

Eu gerei um projeto CLI e recebo o mesmo erro

Ok, vou tentar dar uma olhada nisso esta noite

Eu experimento o mesmo problema ao tentar construir com angular universal. @tjoskar , você já pensou em usar ng-packagr para construir sua biblioteca? Você pode construir e agrupar sua biblioteca nos formatos FESM2015, FESM5 e UMD.
Dê uma olhada aqui: https://github.com/ng-packagr/ng-packaged/blob/master/package.json#L11 (exemplo de projeto usando ng-packagr).

// Parece que é o problema comum para universais, por exemplo. https://github.com/angular/angular-cli/issues/7200
// Eu tenho essa configuração no meu projeto
// substitua este: --- " compile: server ": "tsc -p server.tsconfig.json"
// com isto: --- " compile: server ": "node --max_old_space_size = 3072 node_modules / webpack / bin / webpack.js --config webpack.server.config.js --progress --colors"

// em seguida, crie webpack.server.config.js adicione o código abaixo:

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'),
      {}
    )
  ]
};

// meu servidor.ts

`` `
import 'zone.js / dist / zone-node';
importar {enableProdMode} de '@ angular / core';
// Express Engine
importar {ngExpressEngine} de '@ nguniversal / express-engine';
// Importar mapa de módulo para carregamento lento
importar {fornecerModuleMap} de '@ nguniversal / module-map-ngfactory-loader';

importar * como expresso de 'expresso';
import {join} de 'path';

// O servidor é renderizado com mais rapidez no modo Prod (o modo dev nunca é necessário)
enableProdMode ();

// servidor expresso
const app = express ();

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

// * NOTA :: deixe como require () já que este arquivo é construído dinamicamente a partir do webpack
const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = requer ('./ dist / server / main');

// Nosso motor expresso universal (encontrado em https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine ('html', ngExpressEngine ({
bootstrap: AppServerModuleNgFactory,
provedores: [
fornecerModuleMap (LAZY_MODULE_MAP)
]
}));

app.set ('view engine', 'html');
app.set ('visualizações', DIST_FOLDER);

// Exemplo de endpoints da API Express Rest
// app.get ('/ api / *', (req, res) => {});// Veicula arquivos estáticos do / navegadorapp.get (' . *', express.static (DIST_FOLDER, {
maxAge: '1y'
}));

// Todas as rotas regulares usam o motor universal
app.get ('*', (req, res) => {
res.render ('índice', {req});
});

// Inicie o servidor Node
app.listen (PORTA, () => {
console.log ( Node Express server listening on http://localhost:${PORT} );
});

Por enquanto, isso deve funcionar.

@tjoskar Eu usei seu branch e parece que ele

@Loutrinos , desculpem a demora. Você pode tentar instalar [email protected] (beta) para ver se isso resolve o problema. Obrigado.

@tjoskar Vejo na versão 5.1.0 que a estrutura é diferente. Por enquanto, não há problema, pois é uma versão beta.
Com 5.1.0 Angular Universal não quebra mais: P

@Loutrinos ,

Eu vejo na versão 5.1.0 que a estrutura é diferente

Desculpe por isso, eu criei uma nova versão ([email protected]) com a mesma estrutura de antes. Minhas semanas anteriores foram bastante agitadas, mas agora estou de volta ao trabalho, então deixe-me saber como funciona para você.

Depois de instalar a versão 5.1.1 e estou recebendo este erro:
ReferenceError: IntersectionObserver is not defined

@agustintarifa Como é o seu arquivo tsconfig.json ?

Acabei de criar este repositório: https://github.com/tjoskar/ng-lazyload-image-bugs/tree/master/370-universal-starter-compile e parece funcionar bem. Clonei https://github.com/angular/universal-starter , instalei ng-lazyload-image (npm install [email protected]), adicionei uma imagem , compilado com npm run build:prerender e em seguida, iniciei o servidor: node dist/server.js .

Obrigado pela resposta @tjoskar
Está funcionando agora, mudei meus módulos.
No app.module use: LazyLoadImageModule.forRoot({}),
E nos outros módulos: LazyLoadImageModule.forRoot({ preset: intersectionObserverPreset, }),

O único problema, o deslocamento não está funcionando na parte superior para ver a primeira imagem preciso rolar 1px no mínimo e depois a outra carrega quando estiverem visíveis, quero carregar as imagens 200px antes

Humm .. No meu exemplo acima , declaro apenas LazyLoadImageModule em app.module e está funcionando bem e não consigo reproduzir o erro. Seria muito útil se alguém pudesse criar um pequeno repositório para reproduzir o erro (ou fornecer instruções passo a passo).

@agustintarifa , Em relação ao problema de compensação. Você pode criar um novo problema para isso?

Olá, quando podemos esperar a versão 5.1.1 estável, não a beta? Porque eu também tenho esse problema com SSR.

@ vytautas-pranskunas-, vou lançá-lo amanhã com algumas outras correções menores.

Siunds ótimo 👍

Na segunda-feira, 1º de abril de 2019, 21h17 Oskar Karlsson [email protected]
escreveu:

@ vytautas-pranskunas- https://github.com/vytautas-pranskunas- , eu vou
libere-o amanhã com algumas outras correções menores.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/tjoskar/ng-lazyload-image/issues/370#issuecomment-478709421 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/ADvMl18aKahOsS6vr4C4h4Tagwy2p4TNks5vclsrgaJpZM4Z0lGg
.

[email protected] já foi lançado. Informe se o erro ainda ocorre.

@tjoskar Estou usando 6.0.0 e o problema continua aqui.

// app.module.ts

LazyLoadImageModule.forRoot({
  preset: intersectionObserverPreset
}),

E quando inicio o servidor SSR, obtive:

ReferenceError: IntersectionObserver is not defined

ref # 396

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

vincent-cm picture vincent-cm  ·  10Comentários

sandeepdussa picture sandeepdussa  ·  9Comentários

walfro picture walfro  ·  11Comentários

vugar005 picture vugar005  ·  10Comentários

AzerHeshim picture AzerHeshim  ·  5Comentários