Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何通过npm将自定义库导入Ember_Javascript_Ember.js_Npm_Ecmascript 6 - Fatal编程技术网

Javascript 如何通过npm将自定义库导入Ember

Javascript 如何通过npm将自定义库导入Ember,javascript,ember.js,npm,ecmascript-6,Javascript,Ember.js,Npm,Ecmascript 6,尽管关于它的博客文章似乎太多了,但我仍然在努力通过npm将自定义库作为我的余烬应用程序的依赖项 我已经编写了一个WebGL库,目前已通过npm从私有存储库将其导入我的Ember应用程序。这项工作目前正在进行,并且正在生产中,但工作流程有些笨拙。该库是使用NodeJS模块(require->export.modules)编写的。目前我只是在我的src文件上使用babel,这会导致生成一个文件夹,其中ES5版本的文件仍然是分开的 然后我有一个如下所示的索引文件: var Helper = requi

尽管关于它的博客文章似乎太多了,但我仍然在努力通过npm将自定义库作为我的余烬应用程序的依赖项

我已经编写了一个WebGL库,目前已通过npm从私有存储库将其导入我的Ember应用程序。这项工作目前正在进行,并且正在生产中,但工作流程有些笨拙。该库是使用NodeJS模块(require->export.modules)编写的。目前我只是在我的src文件上使用babel,这会导致生成一个文件夹,其中ES5版本的文件仍然是分开的

然后我有一个如下所示的索引文件:

var Helper = require('./com/XXXX/utils/Helper');
module.exports = {
  Module1: require('./com/XXXX/media/Module1'),
  Module2: require('./com/XXXX/media/Module2'),
  Module3: require("./com/XXXX/media/Module3"),
  Module4: require('./Module4'),
  Module5: require('./com/XXXX/media/Module5'),
  Module6: Helper.Module6,
  Module7: Helper.Module7
};
class Module5 {
  //Magic rendering code
}
module.exports = Module5;
export default class Module5 {
  //Magic rendering code
}
(function() {
  function mediaVendorModule(moduleName) {
    'use strict';
    var MyModule = self['ModuleNamespace']; // Global
    return function() {
      return {
        'default': MyModule[moduleName]
      };
    };
  }
  function helperVendorModule() {
    'use strict';
    var MyModule = self['ModuleNamespace']; // Global
    return {
      Module6: MyModule.helper.Module6,
      Module7: MyModule.helper.Module7
    };
  }
  define('com/XXXX/media/Module4', [], mediaVendorModule('Module4'));
  define('com/XXXX/media/Module1', [], mediaVendorModule('Module1'));
  define('com/XXXX/media/Module2', [], mediaVendorModule('Module2'));
  define('com/XXXX/media/Module3', [], mediaVendorModule('Module3'));
  define('com/XXXX/media/Module5', [], mediaVendorModule('Module5'));
  define('com/XXXX/Helper', [], helperVendorModule);
})();
使用npm,我可以将此构建目录安装到我的Ember应用程序中,并使用以下语法导入我需要的模块:

import webglRenderLibrary from 'npm:webglRenderLibrary';
const { Module5 } = webglRenderLibrary;
其中Module5是库中的一个类,导出方式如下:

var Helper = require('./com/XXXX/utils/Helper');
module.exports = {
  Module1: require('./com/XXXX/media/Module1'),
  Module2: require('./com/XXXX/media/Module2'),
  Module3: require("./com/XXXX/media/Module3"),
  Module4: require('./Module4'),
  Module5: require('./com/XXXX/media/Module5'),
  Module6: Helper.Module6,
  Module7: Helper.Module7
};
class Module5 {
  //Magic rendering code
}
module.exports = Module5;
export default class Module5 {
  //Magic rendering code
}
(function() {
  function mediaVendorModule(moduleName) {
    'use strict';
    var MyModule = self['ModuleNamespace']; // Global
    return function() {
      return {
        'default': MyModule[moduleName]
      };
    };
  }
  function helperVendorModule() {
    'use strict';
    var MyModule = self['ModuleNamespace']; // Global
    return {
      Module6: MyModule.helper.Module6,
      Module7: MyModule.helper.Module7
    };
  }
  define('com/XXXX/media/Module4', [], mediaVendorModule('Module4'));
  define('com/XXXX/media/Module1', [], mediaVendorModule('Module1'));
  define('com/XXXX/media/Module2', [], mediaVendorModule('Module2'));
  define('com/XXXX/media/Module3', [], mediaVendorModule('Module3'));
  define('com/XXXX/media/Module5', [], mediaVendorModule('Module5'));
  define('com/XXXX/Helper', [], helperVendorModule);
})();
我不必安装任何其他插件,也不必将库文件导入ember供应商文件,因为很多博客帖子都说,为了让它正常工作,你必须这样做。我真的不明白为什么这个方法有效,但它确实有效

“”\_(ツ)_/“”

我从来没有真正喜欢过这个设置/工作流程(也不知道它为什么会工作),所以我正在尝试改进它,但是我在Ember、JS模块等方面的许多知识差距让它变得很困难

我想做的第一件事是将库移到ES6模块(导入->导出).据我所知,ES6模块更加精简,而且是未来的发展趋势,因此我更愿意在我的库中使用它们。更改所有源代码有点耗费人力,但效果很好,使我能够为我的库开发创建一个良好的工作流程

模块5现在看起来像这样:

var Helper = require('./com/XXXX/utils/Helper');
module.exports = {
  Module1: require('./com/XXXX/media/Module1'),
  Module2: require('./com/XXXX/media/Module2'),
  Module3: require("./com/XXXX/media/Module3"),
  Module4: require('./Module4'),
  Module5: require('./com/XXXX/media/Module5'),
  Module6: Helper.Module6,
  Module7: Helper.Module7
};
class Module5 {
  //Magic rendering code
}
module.exports = Module5;
export default class Module5 {
  //Magic rendering code
}
(function() {
  function mediaVendorModule(moduleName) {
    'use strict';
    var MyModule = self['ModuleNamespace']; // Global
    return function() {
      return {
        'default': MyModule[moduleName]
      };
    };
  }
  function helperVendorModule() {
    'use strict';
    var MyModule = self['ModuleNamespace']; // Global
    return {
      Module6: MyModule.helper.Module6,
      Module7: MyModule.helper.Module7
    };
  }
  define('com/XXXX/media/Module4', [], mediaVendorModule('Module4'));
  define('com/XXXX/media/Module1', [], mediaVendorModule('Module1'));
  define('com/XXXX/media/Module2', [], mediaVendorModule('Module2'));
  define('com/XXXX/media/Module3', [], mediaVendorModule('Module3'));
  define('com/XXXX/media/Module5', [], mediaVendorModule('Module5'));
  define('com/XXXX/Helper', [], helperVendorModule);
})();
在库的
package.json
中,我有许多npm脚本正在调用watchify,因此我可以在演示文件中单独测试我的模块

{
  "name": "webglRenderLibrary",
  "main": "dist/js/app.js",
  "version": "2.0.5",
  "author": "JibJab Media",
  "description": "WebGL Render Library",
  "repository": "private.git",
  "scripts": {
    "watch-sass": "sass --watch src/scss/app.scss:demo/css/app.css",
    "watch-js": "watchify src/js/index.js -t babelify -o dist/js/app.js -dv",
    "watch-module1": "watchify src/js/demos/Module1Demo.js -t babelify -o demo/js/Module1Demo.js -dv",
    "watch-module2": "watchify src/js/demos/Module2Demo.js -t babelify -o demo/js/Module2Demo.js -dv",
    "watch-module3": "watchify src/js/demos/Module3Demo.js -t babelify -o demo/js/Module3Demo.js -dv",
    "watch-module4": "watchify src/js/demos/Module4Demo.js -t babelify -o demo/js/Module4Demo.js -dv",
    "watch-module5": "watchify src/js/demos/Module5Demo.js -t babelify -o demo/js/Module5Demo.js -dv",
    "watch-module6": "watchify src/js/demos/Module6Demo.js -t babelify -o demo/js/Module6Demo.js -dv",
    "watch": "npm run watch-sass & npm run watch-module1 & npm run watch-module2 & npm run watch-module3 & npm run watch-module5 & npm run watch-module5 & npm run watch-module6",
    "build-sass": "sass src/scss/app.scss:dist/css/app.css --style compressed",
    "build-js": "browserify src/js/index.js -t [ babelify --presets [ \"env\" ] ] | uglifyjs -mc > dist/js/app.js",
    "build": "npm run build-js & npm run build-sass",
    "test": "mocha --require babel-core/register",
    "test-coverage": "nyc mocha --require babel-core/register"
  },
  "browserify": {
    "transform": [
      "babelify"
    ]
  },
  "dependencies": {
    "babel-preset-env": "1.6.1",
    "babelify": "^7.2.0",
    "opentype.js": "0.8.0"
  },
  "devDependencies": {
    "babel-cli": "*",
    "mocha": "5.0.5",
    "nyc": "11.6.0",
    "watchify": "3.11.0"
  },
  "bugs": {
    "url": "private/issues"
  },
  "homepage": "private#readme",
  "private": true
}
我提出这一切都是为了指出,我对ES6模块的转换进展顺利。我为各个模块编写的测试Js文件编译得很好,可以在测试HTML文件中运行它们,WebGL可以正确呈现

现在,这里是我的知识变得模糊的地方

该库包含7个我想公开的模块,以便Ember应用程序可以使用它们。因此,我在库中有一个
index.js
文件,它只需导入每个模块,然后导出它们。(如果不是这样做的话,请告诉我)

据我所知,这使我能够让browserify/babelify将我的ES6模块库转换成Ember可以使用的东西。在库
package.json
中,我有一个“构建”脚本,它运行browserify、babel和uglify,将我的整个库压缩成
dist/js/app.js
中的一个小型文件,这是入口点t位于库
package.json
中的main下

我在想,这应该是目前在我的余烬应用程序中运行的同一个代码。唯一的区别应该是它已被browseridy放入一个文件中,并用Uglify缩小(如果我错了,请纠正我,我认为我错了).我原以为我不必对我的Ember应用程序进行任何更改,但现在我得到了:

Uncaught TypeError: Module5 is not a constructor
以我以前的方式导入时:

import webglRenderLibrary from 'npm:webglRenderLibrary';
const { Module5 } = webglRenderLibrary;
所有这些都让我产生了几个问题:

  • 为什么我最初的策略是简单地对src代码进行babeling并按描述导入它,而这么多博客文章都在谈论使用brocolli并将其导入供应商文件
  • 如果原来的策略有效,为什么我对新库结构的更改也不起作用呢?我猜这是因为browserify改变了NodeJS模块导出的一些内容,但我在这里的知识是模糊的
  • 对于创建一个包含多个要导出的ES6模块的库,是否像我所做的那样从单个索引文件中导出它们是正确的/必要的?如果不是,那么其他库如何向Ember公开它们的模块(例如
    lodash
  • 我见过许多插件/软件包声称允许将ES6模块导入ember。例如,我的库无法使用这些插件/软件包。有人在类似于我的设置中成功使用过类似的插件/软件包吗?你是如何做到的
  • 如果您正在创建一个自定义库以导入到ember应用程序,您将如何执行此操作
  • ===========================================

    编辑

    我已经找到了一个可行的解决方案,但我并不完全理解它,我也不是它的超级粉丝

    在库
    package.json
    中,我添加了“standalone”参数,它神奇地工作了

    "build-js": "browserify --standalone WebGLRenderLibrary src/js/index.js -t [ babelify --presets [ \"env\" ] ] | uglifyjs -mc > dist/js/app.js",
    
    我不知道它在幕后做了什么,但现在它正在发挥作用。希望很快会有更好的解决方案出现。

    更新:是一个干净的、小的、社区认可的插件,允许NPM模块导入到Ember中,而无需设置、样板文件或增加认知负载。请先使用它。仅在极端情况下使用(遗留代码/不兼容用法)您需要以下手动工作


    如果没有和你一起经历同样的情况,我觉得回答你的问题只是一种猜测。因为我不想错过代表,我将尝试描述我如何完成同样的情况

    首先,在应用程序中包含供应商代码与在加载项中包含供应商代码之间存在细微差异。我的经验是基于创建一个ember加载项。然而,由于应用程序允许在repo加载项中使用加载项,因此加载项的过程可以很容易地在实际应用程序中复制。我还建议单独执行此操作(作为一个单独的插件或回购插件)比作为应用程序本身的一部分更有益

    第一个障碍是确保您希望使用的模块与浏览器兼容,因为实际模块将在浏览器中使用。如果您希望使用的NPM模块是特定于节点的,则