Deploying Package to Salesforce Using JSforce and Gulp.js
Gulp.js is a simple task/build runner to process front-end stuff, which utilizes pipes for streaming data that needs to be processed.
As gulp.js is running on Node.js, various Node.js-based packages - including JSforce - can be used in build scripts.
(All files including build script and source codes of this article is available from here)
First, we assume a project with following directory structure :
├── gulpfile.coffee ├── package.json ├── pkg │ ├── package.xml │ ├── pages │ │ ├── MyAppPage.page │ │ └── MyAppPage.page-meta.xml │ └── staticresources │ ├── MyApp.resource │ └── MyApp.resource-meta.xml └── src ├── images │ └── salesforce.jpg ├── scripts │ └── main.coffee └── styles └── main.less
In this project it has the
pkg/ directory - a package of Force.com metadata objects for example Apex classes or Visualforce pages.
src/ directory includes all static files to be built and archived to a zipped static resource file by gulp.
Building Static Files
When all static files are built, they will be zipped as a static resource file in
gulp = require "gulp" zip = require "gulp-zip" less = require "gulp-less" streamify = require "gulp-streamify" uglify = require "gulp-uglify" minify = require "gulp-minify-css" browserify = require "browserify" source = require "vinyl-source-stream" # Building CSS files from LESS source gulp.task "css", -> gulp.src "./src/styles/main.less" .pipe less() .pipe minify() .pipe gulp.dest "./build/css" # Compile and bundle JS file from CoffeeScript source code gulp.task "js", -> browserify entries: [ "./src/scripts/main.coffee" ] extensions: [ ".coffee" ] .bundle() .pipe source "main.js" .pipe streamify uglify() .pipe gulp.dest "./build/js" # Copy all static files in src directory to temporary build directory gulp.task "statics", -> gulp.src [ "./src/**/*.html", "./src/images/**/*" ], base: "./src" .pipe gulp.dest "./build" # Zip all built files as a static resource file gulp.task "zip", [ "css", "js", "statics" ], -> gulp.src "./build/**/*" .pipe zip("MyApp.resource") .pipe gulp.dest "./pkg/staticresources" # Build gulp.task "build", [ "zip" ]
Deploying to Salesforce
As all frontend files are built, now the time to upload and deploy the Force.com package to Salesforce.
The deploy task first zips package directory, pipe it to
forceDeploy stream which accepts zipped file contents and
pass it to JSforce
Metadata#deploy() API call.
through2 = require "through2" jsforce = require "jsforce" ### # Returns a stream pipe for deploying zipped package to Salesforce ### forceDeploy = (username, password) -> through2.obj (file, enc, callback) -> conn = new jsforce.Connection() conn.login username, password .then -> conn.metadata.deploy(file.contents).complete(details: true) .then (res) -> if res.details?.componentFailures console.error res.details?.componentFailures return callback(new Error('Deploy failed.')) callback() , (err) -> console.error(err) callback(err) ### # Deploying package to Salesforce ### gulp.task "deploy", -> gulp.src "./pkg/**/*", base: "." .pipe zip("pkg.zip") .pipe forceDeploy(process.env.SF_USERNAME, process.env.SF_PASSWORD) # Default entry point gulp.task "default", [ "build", "deploy" ]
Now you can build and deploy all files to Salesforce by following command :
$ SF_USERNAMEfirstname.lastname@example.org SF_PASSWORD=yourpassword gulp
If you have installed foreman, you can prepare
.env file in your project with above credentials and execute following :
$ foreman run gulp
Of course you can combine
gulp.watch to watch file changes and automatically deploy to Salesforce when a change happens.
gulp.task "watch", -> gulp.watch "./src/**/*", [ "build" ] gulp.watch "./pkg/**/*", [ "deploy" ]
gulp watch to start watching file changes.
$ foreman run gulp watch [20:57:46] Requiring external module coffee-script/register [20:57:49] Using gulpfile /tmp/gulp-jsforce-example/gulpfile.coffee [20:57:49] Starting 'watch'... [20:57:49] Finished 'watch' after 44 ms