I have created a new Cordova app using
cordova create MyApp
I wanted to use a couple of web libraries (no dependency on node.js) and so I installed them with npm. E.g.
npm install onsenui vue-onsenui --save-dev
The directory structure looks like:
config.xml
hooks/
node_modules/
package.json
platforms/
plugins/
res/
www/
The index.html file in www has script tags to include the libraries
<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>
When running the cordova run browser
command, the web server runs fine and displays the page as it should, including loading the cordova.js file, but it returns 404 for the other libraries.
Is there a way to use these node modules in Cordova without copying them into the www directory?
Is there a way to use these node modules in Cordova without copying them into the www directory?
No, not easily: the contents of the www
directory gets deployed to the native platform project by Cordova, unless explicitly copied by a hook script.
You could copy/symlink them into the www
folder manually or use a hook script to automate this.
Use the npm package: cordova-import-npm
You can use a hook before cordova prepare
, that is, when the files are assembled for compiling.
config.xml
and add this line (not inside any platform but in the root, i.e. inside <widget
):<hook src="hooks/importNpmPackages.js" type="before_prepare"/>
hooks/importNpmPackages.js
with this contentconst 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)
}
As you can see in this file I am copying jquery and bootsrap files using a function copyFile
with this syntax:
copyFile(
'<npmPackageName>',
'<path/of/originFile/relative/to/packageDir>',
'<path/to/destFile/relative/to/wwwDir>'
)
I use this in all my cordova projects and it works like a charm. That's how I see it
The hook is also triggered upon cordova build
because cordova build
equals to cordova prepare && cordova compile
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With