Ng-lazyload-image: Angular Universal ๋นŒ๋“œ ์‚ฌ์ „ ๋ Œ๋”๋ง ์˜ค๋ฅ˜

์— ๋งŒ๋“  2019๋…„ 01์›” 08์ผ  ยท  23์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: tjoskar/ng-lazyload-image

  • ์ œ์ถœํ•ฉ๋‹ˆ๋‹ค...

    • [x] ๋ฒ„๊ทธ ๋ณด๊ณ ์„œ
    • [ ] ๊ธฐ๋Šฅ ์š”์ฒญ
    • [ ] ์ง€์› ์š”์ฒญ
  • ๊ธฐ๋Šฅ ์„ ์š”์ฒญํ•˜๊ฑฐ๋‚˜ ๋ฒ„๊ทธ๋ฅผ ๋ณด๊ณ  ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?
    ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฐ Angular Universal ๋นŒ๋“œ ์‚ฌ์ „ ๋ Œ๋”๋ง ๊ธฐ๋Šฅ์˜ ๋ฒ„๊ทธ

  • ํ˜„์žฌ ํ–‰๋™์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?
    ๋ช…๋ น์„ ์‹คํ–‰ํ•  ๋•Œ:
    npm run build:prerender

๊ทธ๊ฒƒ์€ ์ž‘๋™ํ•œ๋‹ค:
"generate:prerender": "cd dist && node prerender",

๊ทธ๋Ÿฐ ๋‹ค์Œ ์˜ค๋ฅ˜์™€ ํ•จ๊ป˜ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.
```/node_modules/ng-lazyload-image/src/lazyload-image.module.js:1
(ํ•จ์ˆ˜(๋‚ด๋ณด๋‚ด๊ธฐ, ์š”๊ตฌ, ๋ชจ๋“ˆ, __filename, __dirname) { import { NgModule } from '@angular/core';
^^^^^^

SyntaxError: ์˜ˆ๊ธฐ์น˜ ์•Š์€ ํ† ํฐ ๊ฐ€์ ธ์˜ค๊ธฐ
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)
ํ•„์š” ์‹œ(internal/module.js:11:18)
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",

์ ‘๊ทผ๋ฒ• 1
ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ฃจํŠธ ํŒจ์น˜:
npm install @babel/cli @babel/core @babel/preset-env @babel/plugin-transform-modules-umd

ํ”Œ๋Ÿฌ๊ทธ์ธ ํด๋”์˜ ๋ฃจํŠธ์— .babelrc ํŒŒ์ผ ์ถ”๊ฐ€:

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

ํ”Œ๋Ÿฌ๊ทธ์ธ 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"
}

๊ทธ๋Ÿฐ ๋‹ค์Œ ๋นŒ๋“œ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
npm run build:es5 && npm run build:umd

๋‚ด ์ž์‹ ์˜ ํ”„๋กœ์ ํŠธ tsconfig.json์— ์ถ”๊ฐ€

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

๊ทธ๋Ÿฌ๋‚˜ ์—ฌ์ „ํžˆ Angular Universal์—์„œ ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ ‘๊ทผ๋ฒ• 2
๋‹ค์Œ ์œ„์น˜์—์„œ ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ Typescript ๋นŒ๋“œ ์˜ต์…˜์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
https://github.com/filipesilva/angular-quickstart-lib

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

Angular Universal๋กœ ๋นŒ๋“œ๋ฅผ ์‹œ๋„ํ•˜๋Š” ๋™์•ˆ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. @tjoskar ng-packagr ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด ๋ณด์…จ์Šต๋‹ˆ๊นŒ ? FESM2015, FESM5 ๋ฐ UMD ํ˜•์‹์œผ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ๋ฒˆ๋“คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://github.com/ng-packagr/ng-packaged/blob/master/package.json#L11(ng-packagr์„ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ)์„ ์‚ดํŽด๋ณด์„ธ์š”.

๋ชจ๋“  23 ๋Œ“๊ธ€

๋‚˜๋Š” ๋˜ํ•œ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. Angular Universal์ด ์„ค์น˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

``` node_modules\ng-lazyload-image\index.js:1
(ํ•จ์ˆ˜(๋‚ด๋ณด๋‚ด๊ธฐ, ์š”๊ตฌ, ๋ชจ๋“ˆ, __filename, __dirname) { import { LazyLoadImageDirective } from './src/lazyload-image.directive';
^^^^^^

SyntaxError: ์˜ˆ๊ธฐ์น˜ ์•Š์€ ํ† ํฐ ๊ฐ€์ ธ์˜ค๊ธฐ
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)
ํ•„์š” ์‹œ(internal/module.js:11:18)
ํ‰๊ฐ€ ์‹œ (webpack:///external_%22ng-lazyload-image%22?:1:18) ```

๋‚˜๋Š” 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);
      }
    }
  }

}

๋ชจ๋“ˆ๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ:

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

๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€์— ์‚ฌ์šฉ:
<img src="../assets/placeholder.jpg" srcLazy="../assets/myimage.jpg" alt="Example" appLazyLoadImage />

๋‚˜๋Š” ๋˜ํ•œ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. Angular Universal์ด ์„ค์น˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

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

์ด๊ฒƒ์œผ๋กœ ์ž‘๋™

์ด๊ฒƒ์„ webpack ๊ตฌ์„ฑ์— ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

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

angular universal ๋Š” ComonJS ๋ชจ๋“ˆ๋งŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๊ณ  ng-lazyload-image ๋Š” ๋Œ€์ƒ angular universal ๋กœ ES ๋ชจ๋“ˆ๋งŒ ์žˆ์œผ๋ฏ€๋กœ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

@kmturley๊ฐ€ ์„ค๋ช…ํ•œ ๋Œ€๋กœ ng-lazyload-image ๋Œ€ํ•ด ์—ฌ๋Ÿฌ ๋Œ€์ƒ์„ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ๋˜ํ•œ ๋‚˜๋ฌด ํ”๋“ค๊ธฐ๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

@xmasuku , webpack ๊ตฌ์„ฑ์— ๋Œ€ํ•œ ๋” ์ž์„ธํ•œ ์˜ˆ๋ฅผ ๋“ค์–ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? whitelist ๋Š” ์–ด๋””์— ์‚ฌ์šฉํ•ฉ๋‹ˆ๊นŒ?

@tjoskar ๋‚ด ์‚ฌ์šฉ์ž ์ •์˜ webpack ๋นŒ๋“œ๋ฅผ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ angular cli๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

cli ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ–ˆ๋Š”๋ฐ ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ข‹์•„, ์˜ค๋Š˜ ๋ฐค์— ๊ทธ๊ฒƒ์„ ๋ณด๋ ค๊ณ  ๋…ธ๋ ฅํ• ๊ฑฐ์•ผ

Angular Universal๋กœ ๋นŒ๋“œ๋ฅผ ์‹œ๋„ํ•˜๋Š” ๋™์•ˆ ๋™์ผํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. @tjoskar ng-packagr ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด ๋ณด์…จ์Šต๋‹ˆ๊นŒ ? FESM2015, FESM5 ๋ฐ UMD ํ˜•์‹์œผ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ๋ฒˆ๋“คํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
https://github.com/ng-packagr/ng-packaged/blob/master/package.json#L11(ng-packagr์„ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ)์„ ์‚ดํŽด๋ณด์„ธ์š”.

// ๋ณดํŽธ์ ์ธ ๋ฌธ์ œ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ์˜ˆ. https://github.com/angular/angular-cli/issues/7200
// ๋‚ด ํ”„๋กœ์ ํŠธ์— ์ด ์„ค์ •์ด ์žˆ์Šต๋‹ˆ๋‹ค.
// ์ด๊ฒƒ์„ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค: --- " compile:server ": "tsc -p server.tsconfig.json"
// ๋‹ค์Œ๊ณผ ํ•จ๊ป˜: --- " compile:server ": "node --max_old_space_size=3072 node_modules/webpack/bin/webpack.js --config webpack.server.config.js --progress --colors"

// ๊ทธ๋Ÿฐ ๋‹ค์Œ webpack.server.config.js๋ฅผ ๋งŒ๋“ค๊ณ  ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

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

// ๋‚ด ์„œ๋ฒ„.ts

```
import 'zone.js/dist/zone-node';
'@angular/core'์—์„œ {enableProdMode} ๊ฐ€์ ธ์˜ค๊ธฐ;
// ์ต์Šคํ”„๋ ˆ์Šค ์—”์ง„
'@nguniversal/express-engine'์—์„œ {ngExpressEngine} ๊ฐ€์ ธ์˜ค๊ธฐ;
// ์ง€์—ฐ ๋กœ๋”ฉ์„ ์œ„ํ•œ ๋ชจ๋“ˆ ๋งต ๊ฐ€์ ธ์˜ค๊ธฐ
'@nguniversal/module-map-ngfactory-loader'์—์„œ {provideModuleMap} ๊ฐ€์ ธ์˜ค๊ธฐ;

import * '์ต์Šคํ”„๋ ˆ์Šค'์—์„œ ์ต์Šคํ”„๋ ˆ์Šค๋กœ;
'๊ฒฝ๋กœ'์—์„œ {join} ๊ฐ€์ ธ์˜ค๊ธฐ;

// ๋” ๋น ๋ฅธ ์„œ๋ฒ„ ๋ Œ๋”๋ง w/ Prod ๋ชจ๋“œ(๊ฐœ๋ฐœ ๋ชจ๋“œ๋Š” ํ•„์š”ํ•˜์ง€ ์•Š์Œ)
enableProdMode();

// ์ต์Šคํ”„๋ ˆ์Šค ์„œ๋ฒ„
const ์•ฑ = ์ต์Šคํ”„๋ ˆ์Šค();

const ํฌํŠธ = process.env.PORT || 4000;
const DIST_FOLDER = Join(process.cwd(), 'dist/browser');

// * ์ฐธ๊ณ : ์ด ํŒŒ์ผ์€ ์›นํŒฉ์—์„œ ๋™์ ์œผ๋กœ ๋นŒ๋“œ๋˜๋ฏ€๋กœ ์ด๊ฒƒ์„ require()๋กœ ๋‘ก๋‹ˆ๋‹ค.
const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist/server/main');

// ์œ ๋‹ˆ๋ฒ„์…œ ์ต์Šคํ”„๋ ˆ์Šค ์—”์ง„(https://github.com/angular/universal/tree/master/modules/express-engine์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Œ)
app.engine('html', ngExpressEngine({
๋ถ€ํŠธ์ŠคํŠธ๋žฉ: AppServerModuleNgFactory,
๊ณต๊ธ‰์ž: [
์ œ๊ณต ๋ชจ๋“ˆ ๋งต(LAZY_MODULE_MAP)
]
}));

app.set('๋ณด๊ธฐ ์—”์ง„', 'html');
app.set('๋ณด๊ธฐ', DIST_FOLDER);

// Express Rest API ์—”๋“œํฌ์ธํŠธ ์˜ˆ์‹œ
// app.get('/api/ *', (req, res) => { });// /browser์—์„œ ์ •์  ํŒŒ์ผ ์ œ๊ณตapp.get(' .*', express.static(DIST_FOLDER, {
maxAge: '1๋…„'
}));

// ๋ชจ๋“  ์ผ๋ฐ˜ ๊ฒฝ๋กœ๋Š” ์œ ๋‹ˆ๋ฒ„์„ค ์—”์ง„์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
app.get('*', (์š”์ฒญ, ํ•ด์ƒ๋„) => {
res.render('์ƒ‰์ธ', { ์š”์ฒญ });
});

// ๋…ธ๋“œ ์„œ๋ฒ„ ์‹œ์ž‘
app.listen(ํฌํŠธ, () => {
console.log( Node Express server listening on http://localhost:${PORT} );
});

ํ˜„์žฌ๋กœ์„œ๋Š” ์ด๊ฒƒ์ด ์ž‘๋™ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@tjoskar ๊ท€ํ•˜์˜ ๋ถ„๊ธฐ๋ฅผ ์‚ฌ์šฉํ–ˆ์œผ๋ฉฐ ๋นŒ๋“œ ์˜ค๋ฅ˜ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์–ธ์ œ ๋ณ‘ํ•ฉํ•˜์—ฌ ์ถœ์‹œํ•  ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@Loutrinos , ๋Šฆ์–ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. [email protected] (๋ฒ ํƒ€)๋ฅผ ์„ค์น˜ํ•˜์—ฌ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๊ฐ์‚ฌ ํ•ด์š”.

@tjoskar 5.1.0 ๋ฆด๋ฆฌ์Šค์—์„œ ๊ตฌ์กฐ๊ฐ€ ๋‹ค๋ฅด๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฒ ํƒ€ ๋ฆด๋ฆฌ์Šค์ด๋ฏ€๋กœ ์ง€๊ธˆ์€ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค.
5.1.0 Angular Universal์€ ๋” ์ด์ƒ ๊นจ์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค :P

@๋ฃจํŠธ๋ฆฌ๋…ธ์Šค

5.1.0 ๋ฆด๋ฆฌ์Šค์—์„œ ๊ตฌ์กฐ๊ฐ€ ๋‹ค๋ฅธ ๊ฒƒ์„ ๋ด…๋‹ˆ๋‹ค.

์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์ด์ „๊ณผ ๋™์ผํ•œ ๊ตฌ์กฐ๋กœ ์ƒˆ ๋ฆด๋ฆฌ์Šค([email protected])๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์ง€๋‚œ ๋ช‡ ์ฃผ๊ฐ„์€ ๋งค์šฐ ๋ฐ”๋นด์ง€๋งŒ ์ด์ œ ๋‹ค์‹œ ์—…๋ฌด์— ๋ณต๊ท€ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ๋˜๋Š”์ง€ ์•Œ๋ ค์ฃผ์„ธ์š”.

5.1.1 ๋ฒ„์ „์„ ์„ค์น˜ํ•œ ํ›„ ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
ReferenceError: IntersectionObserver is not defined

@agustintarifa tsconfig.json ํŒŒ์ผ์€ ์–ด๋–ป๊ฒŒ ์ƒ๊ฒผ๋‚˜์š”?

๋ฐฉ๊ธˆ ์ด ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค: https://github.com/tjoskar/ng-lazyload-image-bugs/tree/master/370-universal-starter-compile ํ•˜๊ณ  ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. https://github.com/angular/universal-starter ๋ณต์ œํ•˜๊ณ  ng-lazyload-image (npm install [email protected] ์„ค์น˜)๋ฅผ ์„ค์น˜ํ•˜๊ณ  npm run build:prerender ์ปดํŒŒ์ผ๋œ ์ด๋ฏธ์ง€๋ฅผ ์ถ”๊ฐ€ ํ•˜๊ณ  ๊ทธ๋Ÿฐ ๋‹ค์Œ node dist/server.js ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

@tjoskar ๋‹ต๋ณ€ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.
์ง€๊ธˆ ์ž‘๋™ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋ชจ๋“ˆ์„ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.
app.module ์‚ฌ์šฉ: LazyLoadImageModule.forRoot({}),
๊ทธ๋ฆฌ๊ณ  ๋‹ค๋ฅธ ๋ชจ๋“ˆ์—์„œ: LazyLoadImageModule.forRoot({ preset: intersectionObserverPreset, }),

์œ ์ผํ•œ ๋ฌธ์ œ๋Š” ์˜คํ”„์…‹์ด ๋งจ ์œ„์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์•„ ์ฒซ ๋ฒˆ์งธ ์ด๋ฏธ์ง€๋ฅผ ๋ณด๋ ค๋ฉด ์ตœ์†Œํ•œ 1px๋ฅผ ์Šคํฌ๋กคํ•ด์•ผ ํ•˜๊ณ  ๋‹ค๋ฅธ ์ด๋ฏธ์ง€๊ฐ€ ํ‘œ์‹œ๋  ๋•Œ ๋กœ๋“œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ์ „์— ์ด๋ฏธ์ง€๋ฅผ 200px ๋กœ๋“œํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

HUMM๋Š” ..์—์„œ ๋‚ด ์œ„์˜ ์˜ˆ ๋‚œ ๋‹จ์ง€ ์„ ์–ธ LazyLoadImageModule ์—์„œ app.module ํ•˜๊ณ  ์ž˜ ์ž‘๋™ํ•˜๊ณ  ์ •๋ง ์˜ค๋ฅ˜๋ฅผ ์žฌํ˜„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์˜ค๋ฅ˜๋ฅผ ์žฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์€ ์ €์žฅ์†Œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋ฉด(๋˜๋Š” ๋‹จ๊ณ„๋ณ„ ์ง€์นจ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด) ๋งค์šฐ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@agustintarifa , ์˜คํ”„์…‹ ๋ฌธ์ œ์— ๋Œ€ํ•ด. ๋‹น์‹ ์€ ๊ทธ๊ฒƒ์— ๋Œ€ํ•œ ์ƒˆ๋กœ์šด ๋ฌธ์ œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

์•ˆ๋…•ํ•˜์„ธ์š”, ๋ฒ ํƒ€๊ฐ€ ์•„๋‹Œ ์•ˆ์ •์ ์ธ v5.1.1์„ ์–ธ์ œ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? SSR์—๋„ ์ด ๋ฌธ์ œ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

@vytautas-pranskunas-, ๋‹ค๋ฅธ ์ž‘์€ ์ˆ˜์ • ์‚ฌํ•ญ๊ณผ ํ•จ๊ป˜ ๋‚ด์ผ ์ถœ์‹œํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

๋Œ€๋‹จํ•ด ๐Ÿ‘

2019๋…„ 4์›” 1์ผ ์›”์š”์ผ ์˜คํ›„ 9:17 Oskar Karlsson [email protected]
์ผ๋‹ค:

@vytautas-pranskunas- https://github.com/vytautas-pranskunas- , ๋‚˜๋Š”
๋‹ค๋ฅธ ์ž‘์€ ์ˆ˜์ • ์‚ฌํ•ญ๊ณผ ํ•จ๊ป˜ ๋‚ด์ผ ๋ฆด๋ฆฌ์Šคํ•˜์‹ญ์‹œ์˜ค.

โ€”
๋‹น์‹ ์ด ์–ธ๊ธ‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธ
https://github.com/tjoskar/ng-lazyload-image/issues/370#issuecomment-478709421 ,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/ADvMl18aKahOsS6vr4C4h4Tagwy2p4TNks5vclsrgaJpZM4Z0lGg
.

[email protected] ์ด(๊ฐ€) ์ถœ์‹œ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋ฅ˜๊ฐ€ ๊ณ„์† ๋ฐœ์ƒํ•œ๋‹ค๊ณ  ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค.

@tjoskar ๋‚˜๋Š” 6.0.0 ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋ฌธ์ œ๋Š” ์—ฌ๊ธฐ์—์„œ ๊ณ„์†๋ฉ๋‹ˆ๋‹ค.

// app.module.ts

LazyLoadImageModule.forRoot({
  preset: intersectionObserverPreset
}),

๊ทธ๋ฆฌ๊ณ  SSR ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•  ๋•Œ ๋‹ค์Œ์„ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค.

ReferenceError: IntersectionObserver is not defined

์ฐธ์กฐ #396

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰