【问题标题】:What is the right way to use lodash-es in Angular Universal?在 Angular Universal 中使用 lodash-es 的正确方法是什么?
【发布时间】:2017-12-08 15:22:15
【问题描述】:

当我将导入从 lodash 替换为 lodash-es 时,Angular Universal 服务器中断。但是当我运行ng serve 时,一切都很好。我想使用 lodash-es,这样我就可以在我的 Angular SPA 中挑选 lodash 函数并缩小捆绑包的大小。

我采取的步骤:npm 卸载 lodash,npm 安装 lodash-es,并像这样替换我的导入:

发件人:import { find as _find } from "lodash";

收件人:import { find as _find } from "lodash-es"

这是我收到的服务器错误:

/usr/src/app/node_modules/lodash-es/lodash.js:10
export { default as add } from './add.js';
^^^^^^
SyntaxError: Unexpected token export
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:599:28)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Module.require (module.js:579:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/usr/src/app/dist/server.js:246:18)

server.ts

import "zone.js/dist/zone-node";
import "reflect-metadata";
import { renderModuleFactory } from "@angular/platform-server";
import { enableProdMode } from "@angular/core";

import * as express from "express";
import * as minifyHTML from "express-minify-html";
import { join } from "path";
import { readFileSync } from "fs";

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
const app = express();

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

// Our index.html we'll use as our template
const template = readFileSync(
  join(DIST_FOLDER, "browser", "index.html")
).toString();

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {
  AppServerModuleNgFactory,
  LAZY_MODULE_MAP
} = require("./dist/server/main.bundle");

// Express Engine
import { ngExpressEngine } from "@nguniversal/express-engine";
// Import module map for lazy loading
import { provideModuleMap } from "@nguniversal/module-map-ngfactory-loader";

app.use(
  minifyHTML({
    override: true,
    exception_url: false,
    htmlMinifier: {
      removeComments: true,
      collapseWhitespace: true,
      collapseBooleanAttributes: true,
      removeAttributeQuotes: true,
      removeEmptyAttributes: true,
      minifyJS: true,
      minifyCSS: true
    }
  })
);

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine(
  "html",
  ngExpressEngine({
    bootstrap: AppServerModuleNgFactory
  })
);

app.set("view engine", "html");
app.set("views", join(DIST_FOLDER, "browser"));

/* - Example Express Rest API endpoints -
  app.get('/api/**', (req, res) => { });
*/

// Server static files from /browser
app.get(
  "*.*",
  express.static(join(DIST_FOLDER, "browser"), {
    maxAge: "1y"
  })
);

// ALl regular routes use the Universal engine
app.get("*", (req, res) => {
  res.render("index", { req });
});

// Start up the Node server
app.listen(PORT, () => {
  console.log(`Node Express server listening on http://localhost:${PORT}`);
});

这是 webpack.server.config.js(可能相关?):

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

module.exports = {
  entry: { server: "./server.ts" },
  resolve: { extensions: [".ts", ".js"] },
  target: "node",
  externals: [nodeExternals()],
  output: {
    path: path.join(__dirname, "dist"),
    filename: "[name].js"
  },
  module: {
    rules: [{ test: /\.ts$/, loader: "ts-loader" }]
  },
  plugins: [
    new webpack.DefinePlugin({
      window: undefined,
      document: undefined
    }),
    new webpack.ContextReplacementPlugin(
      /(.+)?angular(\\|\/)core(.+)?/,
      path.join(__dirname, "src"), // location of your src
      {} // a map of your routes
    ),
    new webpack.ContextReplacementPlugin(
      /(.+)?express(\\|\/)(.+)?/,
      path.join(__dirname, "src")
    )
  ]
};

【问题讨论】:

  • 无耻插件:我制作了一个可以为您工作的小库:micro-dash。它有许多 lodash 函数(目前有 42 个)和 much 更小的包。但它接受的论点不太灵活。但如果它对你有用,请检查一下!
  • 查看链接stackoverflow.com/questions/43168486/…。尝试将 lodash-es 列入白名单
  • 你明白了!我只需要将 lodash-es 列入白名单。我发布了一个答案以添加细节。谢谢大卫。
  • 我在 dev.to dev.to/johnphamous/…987654323@找到了这篇简洁的文章

标签: angular lodash angular-universal


【解决方案1】:

解决方案是将 lodash-es 列入白名单,正如 David 在 cmets 中对原始问题所建议的那样。具体来说,现在 webpack.server.config.js 看起来像这样:

...
  externals: [
    nodeExternals({
      whitelist: [/^lodash-es/]
    })
  ],
...

【讨论】:

    【解决方案2】:

    Angular 2+ 是 typescript .. 所以你需要使用下面的命令从 npm 安装 @types/lodash

    npm install --save @types/lodash
    

    然后你需要在组件中导入它:

    import * as lodash from 'lodash';
    

    你可以像使用 lodash 一样

    lodash.find()  etc...
    

    【讨论】:

    • 不,将整个库导入到我的组件中。我想通过解构来挑选 lodash 函数以保持我的包小。安装@types/lodash 是一个很好的提示,但之后它仍然不起作用。
    • 如果您想要特定功能,只需使用 import { find } from 'lodash' 导入该功能;
    猜你喜欢
    • 1970-01-01
    • 2017-06-18
    • 2019-05-07
    • 1970-01-01
    • 1970-01-01
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多