我正在提交一个...
您要请求功能还是报告错误?
您的库和 Angular Universal 构建预渲染功能存在错误
目前的行为是什么?
运行命令时:
npm run build:prerender
它运行:
"generate:prerender": "cd dist && node prerender",
然后失败并出现错误:
```/node_modules/ng-lazyload-image/src/lazyload-image.module.js:1
(function (exports, require, module, __filename, __dirname) { import { NgModule } from '@angular/core';
^^^^^^
语法错误:意外的令牌导入
在 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)
在要求(内部/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",
方法一
修补您的插件根目录:
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 相同的错误:(
方法二
在示例项目中使用 Typescript 构建选项:
https://github.com/filipesilva/angular-quickstart-lib
我也遇到了同样的错误,我安装了 angular Universal
``` node_modules\ng-lazyload-image\index.js:1
(功能(出口,要求,模块,__filename,__dirname){ import { LazyLoadImageDirective } from './src/lazyload-image.directive';
^^^^^^
语法错误:意外的令牌导入
在 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)
在要求(内部/module.js:11:18)
在 eval (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
只有 ES 模块作为目标angular universal
失败。
我想我们必须为ng-lazyload-image
设置多个目标,正如@kmturley所描述的那样。 但这也意味着摇树将不起作用。
@xmasuku ,你能给出一个更详细的 webpack 配置示例吗? 你在哪里使用whitelist
?
@tjoskar我使用了我的自定义 webpack 构建,我没有使用 angular cli
我已经生成了一个 cli 项目,但我得到了同样的错误
好的,我今晚试试看
我在尝试使用 angular Universal 构建时遇到了同样的问题。 @tjoskar您是否考虑过使用ng-packagr
来构建您的库? 您可以以 FESM2015、FESM5 和 UMD 格式构建和捆绑您的库。
在这里查看: https :
// 看起来它是通用的常见问题,例如。 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'),
{}
)
]
};
// 我的 server.ts
``
导入 'zone.js/dist/zone-node';
从“@angular/core”导入{enableProdMode};
// 快速引擎
从“@nguniversal/express-engine”导入 {ngExpressEngine};
// 为延迟加载导入模块映射
从'@nguniversal/module-map-ngfactory-loader'导入{provideModuleMap};
import * as express from 'express';
从“路径”导入 {join};
// 使用 Prod 模式更快的服务器渲染(从不需要开发模式)
enableProdMode();
// 快速服务器
const app = express();
const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/browser');
// * 注意 :: 将此保留为 require() 因为此文件是从 webpack 动态构建的
const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist/server/main');
// 我们的通用 express-engine(找到 @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
引导程序:AppServerModuleNgFactory,
供应商: [
提供模块映射(LAZY_MODULE_MAP)
]
}));
app.set('视图引擎', 'html');
app.set('views', DIST_FOLDER);
// 示例 Express Rest API 端点
// app.get('/api/ *', (req, res) => { });// 从 /browser 提供静态文件app.get(' .*', express.static(DIST_FOLDER, {
最大年龄:'1y'
}));
// 所有常规路线都使用通用引擎
app.get('*', (req, res) => {
res.render('index', { req });
});
// 启动节点服务器
app.listen(PORT, () => {
console.log( Node Express server listening on http://localhost:${PORT}
);
});
现在,这应该有效。
@tjoskar我使用了你的分支,它似乎解决了构建错误的问题。 你有什么打算合并和发布的计划吗?
@Loutrinos ,抱歉耽搁了。 您能否尝试安装[email protected]
(测试版)以查看是否可以解决问题。 谢谢。
@tjoskar我在 5.1.0 版本中看到结构不同。 这暂时没问题,因为它是测试版。
有了5.1.0
Angular Universal 就不会再坏了 :P
@Loutrinos ,
我在 5.1.0 版本中看到结构不同
抱歉,我创建了一个与以前结构相同的新版本 ([email protected])。 我前几周一直很忙,但现在我又开始工作了,所以让我知道它对你有什么作用。
安装 5.1.1 版本后,我收到此错误:
ReferenceError: IntersectionObserver is not defined
@agustintarifa你的tsconfig.json
文件是什么样的?
我刚刚创建了这个 repo: https : 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 之前加载图像
嗯.. 在我上面的例子中,我只在app.module
声明了LazyLoadImageModule
app.module
并且它工作正常,我无法真正重现错误。 如果有人可以创建一个小的 repo 来重现错误(或提供分步说明),那将非常有帮助。
@agustintarifa ,关于偏移问题。 你能为此创建一个新问题吗?
嗨,我们什么时候可以期待 v5.1.1 成为稳定版而非 Beta 版? 因为我的 SSR 也有这个问题。
@vytautas-pranskunas-,我将在明天发布一些其他较小的修复程序。
声优👍
2019 年 4 月 1 日星期一晚上 9:17 Oskar Karlsson通知@ github.com
写道:
@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
最有用的评论
我在尝试使用 angular Universal 构建时遇到了同样的问题。 @tjoskar您是否考虑过使用
ng-packagr
来构建您的库? 您可以以 FESM2015、FESM5 和 UMD 格式构建和捆绑您的库。在这里查看: https :