在cordova / phonegap中使用npm包

时间:2014-06-27 07:27:23

标签: cordova npm

我正在尝试使用NPM为我的Cordova项目添加一个包,但要么我正在做一些非常错误的事情,要么我没有得到应该工作的方式......我正在使用最新版本的Cordova(v3 .5.0)。我创建了一个应用程序:

cordova create TestApp
cd TestApp
cordova platform add android
cordova run android

一切正常,应用程序出现在我的Android设备上。现在我想将包'pako'添加到我的应用:https://github.com/nodeca/pako。我仍然在同一个目录(见上文),然后输入“npm install pako”。该软件包安装在“/ node_modules /”中。

然而,当我构建我的Android应用程序(cordova build android / cordova运行android / cordova prepare)时,我所安装的软件包(在“/ node_modules /”目录中)都没有被复制到平台特定文件夹“platforms /安卓/ ...。”。换句话说,如何在Cordova / Phonegap应用程序中使用npm包?这个软件包不应该被cordova cli自动复制到正确的平台吗?

这有可能吗?或者我是否必须使用Grunt创建手动构建脚本,例如当我想使用npm包时?由于我找不到任何例子,我认为我完全走错了路,所以如果有人有一点暗示帮助我朝正确的方向发展,我将非常感激。

提前致谢!

4 个答案:

答案 0 :(得分:1)

添加所有已安装的模块通常不是您想要的,因为它们可能包含应用程序中实际未使用的其他依赖项(如测试工具或grunt任务)。虽然您可以使用npm下载依赖项并使其保持最新,但仍需要在应用程序中手动包含它们。

Grunt和grunt-contrib-copy(如果你想要单独的文件)或grunt-contrib-concat(如果你想要一个文件,通常更好的性能)将是一个解决方案。另一个是Browserify,它支持内置的npm模块。

答案 1 :(得分:1)

TLDR 和简单

使用 npm 包:cordova-import-npm

长问题和DIY

你可以简单地 use a hookcordova prepare 之前,它也在 cordova build 上执行,也就是在汇编文件进行编译时。

编辑您的 config.xml 并添加此行(不在任何平台内,而是在根目录中,即在 <widget 内):

<hook src="hooks/importNpmPackages.js" type="before_prepare"/>

然后使用此内容创建文件 hooks/importNpmPackages.js

const fse = require('fs-extra')
const path = require('path')
const twoSpaces = '  ' // for log indentation
var projectRoot

module.exports = function (context) {
  console.log(`${context.hook} : ${path.relative(context.opts.projectRoot, context.scriptLocation)}`)

  projectRoot = context.opts.projectRoot
  console.log(twoSpaces + 'Project root directory: ' + projectRoot)

  copyFile('jquery', path.join('dist', 'jquery.min.js'), path.join('js', 'res', 'jquery.min.js'))

  copyFile('bootstrap', path.join('dist', 'js', 'bootstrap.min.js'), path.join('js', 'res', 'bootstrap.min.js'))
  copyFile('bootstrap', path.join('dist', 'css', 'bootstrap.min.css'), path.join('css', 'res', 'bootstrap.min.css'))
}

function copyFile (npmPackage, // oficial name of the npm package from which the file is to be copied from
  fileRelativePath, // file path with respect to the main directory of the npm package (node_modules/<package>/)
  destFilePath) { // file's path to where it is copied, relative to the project www/ directory
  
  const packageDirFullpath = path.dirname(require.resolve(path.join(npmPackage, 'package.json')))
  const fileOriginFullPath = path.join(packageDirFullpath, fileRelativePath)
  const fileDestFullPath = path.join(projectRoot, 'www', destFilePath)

  fse.copySync(fileOriginFullPath, fileDestFullPath)

  const consoleMsg = npmPackage + ': ' +
    path.relative(projectRoot, fileOriginFullPath) + ' -> ' +
    path.relative(projectRoot, fileDestFullPath)
  console.log(twoSpaces + consoleMsg)
}

正如您在此文件中看到的,我正在使用具有以下语法的函数 copyFile 复制 jquery 和 bootsrap 文件:

copyFile(
  '<npmPackageName>',
  '<path/of/originFile/relative/to/packageDir>',
  '<path/to/destFile/relative/to/wwwDir>'
)

我在我所有的cordova项目中都使用了它,它就像一个魅力。我是这么看的

enter image description here

钩子也会在 cordova build 上触发,因为 cordova build 等于 cordova prepare && cordova compile

答案 2 :(得分:0)

这可以通过使用挂钩触发before_prepare来实现。

请参阅https://stackoverflow.com/a/46615080/2728710

答案 3 :(得分:0)

使用Webpack和Browserify之类的工具是实现此目的的首选方法。您不仅可以使用Cordova应用程序中的任何模块,而且还可以直接使用树状摇动和性能优化等出色功能。