如何在Cordova中加载node_modules? (网络浏览器模块,而不是node.js特定)

时间:2017-09-28 10:02:31

标签: cordova npm

我使用

创建了一个新的Cordova应用程序
cordova create MyApp

我想使用几个Web库(不依赖于node.js),所以我用npm安装它们。 E.g。

npm install onsenui vue-onsenui --save-dev

目录结构如下:

config.xml
hooks/
node_modules/
package.json
platforms/
plugins/
res/
www/

www中的index.html文件包含脚本标记以包含库

<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript" src="onsenui.js"></script>
<script type="text/javascript" src="vue-onsenui.js"></script>

运行cordova run browser命令时,Web服务器运行正常,并按原样显示页面,包括加载cordova.js文件,但它为其他库返回404。

有没有办法在Cordova中使用这些节点模块而不将它们复制到www目录中?

2 个答案:

答案 0 :(得分:1)

TLDR 和简单

使用 npm 包:cordova-import-npm

长问题和DIY

您可以在 cordova prepare 之前use a hook,即在汇编文件进行编译时。

  1. 编辑您的 config.xml 并添加此行(不在任何平台内,而是在根目录中,即在 <widget 内):
<hook src="hooks/importNpmPackages.js" type="before_prepare"/>
  1. 使用此内容创建文件 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

答案 1 :(得分:0)

  

有没有办法在Cordova中使用这些节点模块而不将它们复制到www目录中?

不,不容易:除非由钩子脚本显式复制,否则Cordova会将www目录的内容部署到本机平台项目。

您可以手动将它们复制/符号链接到www文件夹,或使用钩子脚本自动执行此操作。