首页 > 解决方案 > Ember Fastboot / 不要导入 node_modules 脚本

问题描述

我首先想指出我是从这里交叉发布的:https ://github.com/ember-fastboot/ember-cli-fastboot/issues/621 到目前为止,这个问题还没有引起任何关注,所以我正在打开它到更广泛的社区。

我正在尝试使 ember-cli-slick fastboot 兼容。它使用来自 node_modules 的 slick.js,如下所示:

included: function(app) {
this._super.included(app);

app.import("node_modules/slick-carousel/slick/slick.js");

我正在尝试让 treeforvendor 工作,但运气不佳。我正在关注这里的文档https://www.ember-fastboot.com/docs/addon-author-guide#third-party-dependencies 但我怀疑它的目标是凉亭而不是 npm/node_modules。

treeForVendor(defaultTree) {        
    var browserVendorLib = new Funnel('node_modules/slick-carousel/slick/slick.js');    

    browserVendorLib = map(browserVendorLib, (content) => `if (typeof FastBoot === 'undefined') { ${content} }`);

    return new mergeTrees([defaultTree, browserVendorLib]);
  },

这会导致错误:

构建错误(broccoli-persistent-filter:Mapper)

ENOTDIR:不是目录,scandir 'projectdir/tmp/broccoli_persistent_filtermapper-input_base_path-FOInixjr.tmp/'

我也试过

  treeForVendor(defaultTree) {        
    var map = require("broccoli-stew").map;
    var Funnel = require("broccoli-funnel");
    const mergeTrees = require('broccoli-merge-trees');

    let tree=new Funnel('node_modules/slick-carousel/slick/', {
      destDir: 'slick-carousel',
      files: ['slick.js']
    })

    tree = map(tree, (content) => `if (typeof FastBoot === 'undefined') { ${content} }`);


    return new mergeTrees([defaultTree, tree]);
  },

这至少可以构建..但后来我又回到了 Fastboot 错误

ReferenceError: jQuery 没有定义在 projectfolder/tmp/broccoli_merge_trees-output_path-8cGO0zCl.tmp/assets/node_modules/slick-carousel/slick/slick.js:25:1

我创建了一个干净且空的 Ember 插件项目,仅使用 import 和 treeforvendor 函数来演示问题 https://github.com/MrChriZ/ember-slicker

标签: ember.js

解决方案


有几件事我错过了,也许插件指南可以更清楚。

首先,我认为 Funnel 采用目录路径而不是完整文件路径。最重要的是,路径必须是完整的文件路径。Fastboot Addon Guide 并没有立即明确这一点。
所以这看起来像这样:

const assetDir = path.join(this.project.root, 'node_modules', 'slick-carousel', 'slick');
       var browserVendorLib = new Funnel(assetDir, {
         files: ['slick.js'],
         destDir: 'slick'
       });    

你不能做的是

const assetDir = path.join(this.project.root, 'node_modules', 'slick-carousel', 'slick', 'slick.js);
var browserVendorLib = new Funnel(assetDir);

这抛出:

ENOTDIR:不是目录

我相信是因为漏斗期望的是目录路径而不是文件路径。

其次,在包含的钩子中,Gaurav 在 Github 上正确指出需要将导入语句更改为指向供应商目录。

所以对我来说最终的解决方案是:

treeForVendor(defaultTree) {        
   var map = require("broccoli-stew").map;
   var Funnel = require("broccoli-funnel");
   const mergeTrees = require('broccoli-merge-trees');

   const assetDir = path.join(this.project.root, 'node_modules', 'slick-carousel', 'slick');
   var browserVendorLib = new Funnel(assetDir, {
     files: ['slick.js'],
     destDir: 'slick'
   });    

   browserVendorLib = map(browserVendorLib, (content) => `if (typeof FastBoot === 'undefined') { ${content} }`);

   return new mergeTrees([defaultTree, browserVendorLib]);
 },
 included: function(app) {
   this._super.included(app);

   app.import('node_modules' + '/slick-carousel/slick/slick.css');
   app.import('node_modules'+ '/slick-carousel/slick/slick-theme.css');
   app.import('node_modules' + '/slick-carousel/slick/fonts/slick.ttf', { destDir: 'assets/fonts' });
   app.import('node_modules' + '/slick-carousel/slick/fonts/slick.svg', { destDir: 'assets/fonts' });
   app.import('node_modules' + '/slick-carousel/slick/fonts/slick.eot', { destDir: 'assets/fonts' });
   app.import('node_modules' + '/slick-carousel/slick/fonts/slick.woff', { destDir: 'assets/fonts' });
   app.import('node_modules' + '/slick-carousel/slick/ajax-loader.gif', { destDir: 'assets' });

   // import the above library into vendor.js that was merged with the vendor trees. In browser the library will be eval'd and run
   // In fastboot, the library will not be eval'd
   app.import('vendor/slick/slick.js');
 }

推荐阅读