I have to migrate a frontend build process from Gulp 3.9.1 to Gulp 4.0.2.
The latest Gulp doc says here that a gulpfile can be splitted in various parts placed under a folder named gulpfile.js with an index.js file and all other scripts.
Does Visual Studio 2019 Task Runner Explorer support this kind of configuration or a single gulpfile is needed?
The short answer is yes. Visual Studio support Gulp 4. What happens is Visual Studio is using the old version of Node.js. And it is caused because VS not finding the new node path.
What you have to do to fix it is:
Open visual studio and click in tools.
In the search options search for "External Web Tools".
Add $(PATH) variable on top.
Here is my gulpfile.js as a reference to you.
var gulp = require('gulp');
var path = require('path');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var sourcemaps = require('gulp-sourcemaps');
var open = require('gulp-open');
const minify = require("gulp-minify");
const del = require("del");
var Paths = {
HERE: './',
DIST: 'dist/',
CSS: './wwwroot/assets/css/',
SCRIPTS: './wwwroot/assets/scripts/',
JS: './wwwroot/assets/js/',
IMG: './wwwroot/assets/img/',
SCSS: './assets/scss/**/**'
};
function compileScss() {
return gulp.src(Paths.SCSS_TOOLKIT_SOURCES)
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer())
.pipe(sourcemaps.write(Paths.HERE))
.pipe(gulp.dest(Paths.CSS));
};
function minifyJs() {
return gulp.src('./assets/js/**/**', { allowEmpty: true })
.pipe(minify({ noSource: true }))
.pipe(gulp.dest(Paths.JS));
}
function copyCss() {
return gulp.src('./assets/css/**/**')
.pipe(gulp.dest(Paths.CSS));
};
function copyScripts() {
return gulp.src('./assets/scripts/**/**')
.pipe(gulp.dest(Paths.SCRIPTS));
}
function copyJs() {
return gulp.src('./assets/js/**/**')
.pipe(gulp.dest(Paths.JS));
}
function copyImages() {
return gulp.src('./assets/img/**/**')
.pipe(gulp.dest(Paths.IMG));
}
function copyIco() {
return gulp.src('./assets/favicon.ico')
.pipe(gulp.dest('./wwwroot/'));
}
// Clean assets
function clean() {
return del(["./wwwroot/"]);
}
const build = gulp.parallel(compileScss, minifyJs);
const copy = gulp.parallel(copyCss, copyScripts, copyJs, copyImages, copyIco)
const deploy = gulp.series(clean, build, copy);
exports.clean = clean;
exports.build = build;
exports.copy = copy;
exports.default = deploy;
It just works with Gulp 4x
I have my Gulp functions broke out into multiple files. I have my separate files under a folder called 'Gulp' (variables.js and functions.js) and have my gulp file as below. With the Hub registry it will find all the files to process.
My package.json
{
"version": "1.0.0",
"name": "asp.net",
"private": true,
"devDependencies": {
"gulp": "^4.0.2",
"gulp-concat": "2.6.1",
"gulp-cssmin": "0.2.0",
"gulp-hub": "4.2.0",
"gulp-sass": "4.0.2",
"gulp-uglify": "3.0.2"
},
"dependencies": {
"bootstrap": "5.1.1",
"bootstrap-select": "1.13.12",
"bootstrap4-toggle": "3.6.1",
"bootstrap-datepicker": "1.9.0",
"datatables.net-bs4": "1.10.20",
"datepicker-bootstrap": "^1.9.13",
"font-awesome": "4.7.0",
"jquery": "3.6.0",
"jquery-validation": "1.19.3",
"jquery-validation-unobtrusive": "3.2.12",
"opensans-webkit": "1.1.0",
"popper.js": "1.16.1"
}
}
gulpfile.js
'use strict';
var gulp = require('gulp');
var HubRegistry = require('gulp-hub');
/* load some files into the registry */
var hub = new HubRegistry(['Gulp/*.js']);
/* tell gulp to use the tasks just loaded */
gulp.registry(hub);
variable.js
// #region Root Paths
var paths = {
webroot:
"./wwwroot/",
nodeModules:
"./node_modules/"
};
// #endregion
// JavaScript files
var js = {
// jQuery
jQuery:
paths.nodeModules + "jquery/dist/jquery.js",
jQuery_min:
paths.nodeModules + "jquery/dist/jquery.min.js",
// more js files below ...
}
// Css/Scss files
var css = {
// Bootstrap
bootstrap:
paths.nodeModules + "bootstrap/dist/css/bootstrap.css",
bootstrap_min:
paths.nodeModules + "bootstrap/dist/css/bootstrap.min.css",
// more css files below ...
}
// Font files
var fonts = {
OpenSans: paths.nodeModules + "opensans-webkit/fonts/*.woff*",
FontAwesome: paths.nodeModules + "font-awesome/fonts/*.*"
};
// Folder locations
var folders = {
jsFolder:
paths.webroot + "js/",
cssFolder:
paths.webroot + "css/",
fontFolder:
paths.webroot + "fonts/"
//paths.webroot + "uploads/files/styles-library/fonts/"
};
// Output filenames
var filenames = {
prod_VendorJs:
"vendor.min.js",
prod_VendorCss:
"vendor.min.css"
}
module.exports = {
js: js,
css: css,
fonts: fonts,
folders: folders,
filename: filenames
};
function.js
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var sass = require('gulp-sass');
var cssmin = require('gulp-cssmin');
var variables = require('./variables');
var js = variables.js;
var css = variables.css;
var fonts = variables.fonts;
var folder = variables.folders;
var filename = variables.filename;
// Doing gulp tasks below
Related
I am having difficulties copying some files from my application Resources folder:
var myDocuments = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Library");
// Confirm these paths are OK for iOS too
var root = Path.Combine(myDocuments, "VisitsRota.MacOS");
var styles = Path.Combine(root, "Styles");
var stylesheet = Path.Combine(styles, "ElderlyInfirm-Schedule-v1.css");
var db = Path.Combine(root, "ElderlyInfirmRotaData.xml");
var defaultroot = Path.Combine( ".", "Resources");
// Main folder
if (!Directory.Exists(root))
{
Directory.CreateDirectory(root);
}
// Database
if (!File.Exists(db))
{
var defaultdb = Path.Combine(defaultroot, "ElderlyInfirmRotaData.xml");
File.Copy(defaultdb, db);
}
// Styles folder
if (!Directory.Exists(styles))
{
Directory.CreateDirectory(styles);
}
// Stylesheet
if (!File.Exists(stylesheet))
{
var defaultstylesheet = Path.Combine(defaultroot, "Styles", "ElderlyInfirm-Schedule-v1.css");
File.Copy(defaultstylesheet, stylesheet);
}
The problem is determining the application folders Resources folder, At the moment I get this exception:
What is the correct way to get to the Resources folder (for either iOS or macOS)?
In the IDE I only see just the one Resource folder:
Both of my resources have a Build Action set to Content.
Thank you for pointing me in the right direction to resolve this.
I tried using the result from:
public static string GetExecutingDirectoryName()
{
var location = new Uri(Assembly.GetEntryAssembly().GetName().CodeBase);
return new FileInfo(location.AbsolutePath).Directory.FullName;
}
It was completely wrong.
I am running the app in the Debugger in VS for Mac (macOS build).
I assume that using the Resource folder for these files was OK. Unless there is a better way to do this?
It was much easier to use BundleResource:
var myDocuments = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Library");
// Create the folders first
// Main folder
var root = Path.Combine(myDocuments, "VisitsRota.MacOS");
if (!Directory.Exists(root))
{
Directory.CreateDirectory(root);
}
// Styles folder
var styles = Path.Combine(root, "Styles");
if (!Directory.Exists(styles))
{
Directory.CreateDirectory(styles);
}
// Now copy the files
// Database
var db = Path.Combine(root, "ElderlyInfirmRotaData.xml");
var defaultdb = NSBundle.MainBundle.PathForResource("ElderlyInfirmRotaData", ofType: "xml");
if (!File.Exists(db))
{
File.Copy(defaultdb, db);
}
// Stylesheet
var stylesheet = Path.Combine(styles, "ElderlyInfirm-Schedule-v1.css");
var defaultstylesheet = NSBundle.MainBundle.PathForResource("ElderlyInfirm-Schedule-v1", ofType: "css");
if (!File.Exists(stylesheet))
{
File.Copy(defaultstylesheet, stylesheet);
}
I cannot use the bluetoothSerial functions even though I installed the plugin by running cordova "plugin add cordova-plugin-bluetooth-serial" command in the project folder. I have received no errors and the plugin exists in the plugins folder.
I have tried adding plugin tag to the config.xml,
I have tried adding bluetooth permission to the AndroidManifest.xml
but none helped.
My cordova version is 9.0.0 (cordova-lib#9.0.1)
var app = {
initialize: function()
{
this.bindEvents();
},
bindEvents: function ()
{
document.addEventListener('deviceready',this.onDeviceReady(),
false)},
onDeviceReady: function () {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
window.addEventListener('touchstart', function(event){
console.log(event.touches);
touchX = event.touches[0].pageX;
touchY = event.touches[0].pageY;
console.log(touchX, touchY);
if (touchX <= button1.x + button1.width && touchX >= button1.x)
{
if (touchY <= button1.y + button1.height && touchY >=
button1.y) {
check = 1; // Everything is fine until here.
bluetoothSerial.isEnabled(success(), fail()); // the code
here and below here is never executed.
c.font = "80px Arial";
c.fillText("here",50,50);
}
}
When I debug using chrome://inspect/#devices I receive:
serialBluetooth is not defined error.
why is that happening?
It turned out that it is necessary to include the script tag, cordova.js.
I updated to Ionic 3.5, and after that I get this error, when i try to do cordova build ios:
Invalid data, chunk must be a string or buffer, not object
There is no explanation of why this error is happening. I tried this both with Cordova 7.0.1 and 6.5.0. Interestingly, it works on Windows machine, but not on Mac. I only get the error on Mac. I appreciate any insights or helps.
ionic info
global packages:
#ionic/cli-utils : 1.5.0
Cordova CLI : 7.0.1
Ionic CLI : 3.5.0
local packages:
#ionic/app-scripts : 1.3.7
#ionic/cli-plugin-cordova : 1.4.1
#ionic/cli-plugin-ionic-angular : 1.3.2
Cordova Platforms : android 6.2.3
Ionic Framework : ionic-angular 3.5.3
System:
Node : v7.10.0
OS : Windows 10
Xcode : not installed
ios-deploy : not installed
ios-sim : not installed
npm : 4.6.1
I got the fix from one of the github issue. It just needed correct path for strings.xml.
There is no need to downgrade cordova or cordova-android
The fix is to replace the code in
/cordova-plugin-fcm/scripts/fcm_config_files_process.js as below:
#!/usr/bin/env node
'use strict';
var fs = require('fs');
var path = require('path');
fs.ensureDirSync = function (dir) {
if (!fs.existsSync(dir)) {
dir.split(path.sep).reduce(function (currentPath, folder) {
currentPath += folder + path.sep;
if (!fs.existsSync(currentPath)) {
fs.mkdirSync(currentPath);
}
return currentPath;
}, '');
}
};
var config = fs.readFileSync('config.xml').toString();
var name = getValue(config, 'name');
var IOS_DIR = 'platforms/ios';
var ANDROID_DIR = 'platforms/android';
var PLATFORM = {
IOS: {
dest: [
IOS_DIR + '/' + name + '/Resources/GoogleService-Info.plist',
IOS_DIR + '/' + name + '/Resources/Resources/GoogleService-Info.plist'
],
src: [
'GoogleService-Info.plist',
IOS_DIR + '/www/GoogleService-Info.plist',
'www/GoogleService-Info.plist'
]
},
ANDROID: {
dest: [
ANDROID_DIR + '/google-services.json',
ANDROID_DIR + '/app/google-services.json',
],
src: [
'google-services.json',
ANDROID_DIR + '/assets/www/google-services.json',
'www/google-services.json'
],
stringsXml: ANDROID_DIR + '/app/src/main/res/values/strings.xml'
}
};
// Copy key files to their platform specific folders
if (directoryExists(IOS_DIR)) {
copyKey(PLATFORM.IOS);
}
if (directoryExists(ANDROID_DIR)) {
copyKey(PLATFORM.ANDROID, updateStringsXml)
}
function updateStringsXml(contents) {
var json = JSON.parse(contents);
var strings = fs.readFileSync(PLATFORM.ANDROID.stringsXml).toString();
// strip non-default value
strings = strings.replace(new RegExp('<string name="google_app_id">([^\#<]+?)</string>', 'i'), '');
// strip non-default value
strings = strings.replace(new RegExp('<string name="google_api_key">([^\#<]+?)</string>', 'i'), '');
// strip empty lines
strings = strings.replace(new RegExp('(\r\n|\n|\r)[ \t]*(\r\n|\n|\r)', 'gm'), '$1');
// replace the default value
strings = strings.replace(new RegExp('<string name="google_app_id">([^<]+?)</string>', 'i'), '<string name="google_app_id">' + json.client[0].client_info.mobilesdk_app_id + '</string>');
// replace the default value
strings = strings.replace(new RegExp('<string name="google_api_key">([^<]+?)</string>', 'i'), '<string name="google_api_key">' + json.client[0].api_key[0].current_key + '</string>');
fs.writeFileSync(PLATFORM.ANDROID.stringsXml, strings);
}
function copyKey(platform, callback) {
for (var i = 0; i < platform.src.length; i++) {
var file = platform.src[i];
if (fileExists(file)) {
try {
var contents = fs.readFileSync(file).toString();
try {
platform.dest.forEach(function (destinationPath) {
var folder = destinationPath.substring(0, destinationPath.lastIndexOf('/'));
fs.ensureDirSync(folder);
fs.writeFileSync(destinationPath, contents);
});
} catch (e) {
// skip
}
callback && callback(contents);
} catch (err) {
console.log(err)
}
break;
}
}
}
function getValue(config, name) {
var value = config.match(new RegExp('<' + name + '>(.*?)</' + name + '>', 'i'));
if (value && value[1]) {
return value[1]
} else {
return null
}
}
function fileExists(path) {
try {
return fs.statSync(path).isFile();
} catch (e) {
return false;
}
}
function directoryExists(path) {
try {
return fs.statSync(path).isDirectory();
} catch (e) {
return false;
}
}
For fixing the issue:
Make sure you have copied the above file in "plugins" folder as cordova copies all the cordova-plugins from node_modules directory to plugins directory,
if you have already added the platforms before modifying the file
plugins/cordova-plugin-fcm/scripts/fcm_config_files_process.js, you need to remove the platforms and add again.
#Ari In case you are still having this issue, this is what I did to solve this issue.
I had to edit file "fcm_config_files_process.js" located in folder "plugins/cordova-plugin-fcm/scripts/":
// fs.writeFileSync("platforms/ios/" + name + "/Resources/GoogleService-Info.plist", contents)
For some unknown reason while building the project this line (42) was throwing the error "Invalid data, chunk must be a string or buffer, not object" so what I did was to comment that line and then manually copy the file "GoogleService-Info.plist" to "platforms/ios/" + name + "/Resources/"
Hope this help.
We had this error because our Development Push Certificate from apple was outdated. We have renewed it – and it worked.
Remove default added ios platform when creating Ionic 2 app then add again.
And also remove and add "cordova-fcm-plugin".
ionic platform rm ios
ionic platform add ios
(I failed at getting this working in dart2js so I'm trying in dart dev compiler; but I'd happily take an answer for dart2j!).
If I have test.dart:
void activate() {
print("activating...");
}
and run dartdevc --modules node -o test.js test.dart the output is:
(function() {
'use strict';
const dart_sdk = require('dart_sdk');
const core = dart_sdk.core;
const dart = dart_sdk.dart;
const dartx = dart_sdk.dartx;
const __test = Object.create(null);
let VoidTovoid = () => (VoidTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [])))();
__test.activate = function() {
core.print("activating...");
};
dart.fn(__test.activate, VoidTovoid());
// Exports:
exports.__test = __test;
})();
This means my function is exported as __test.activate but what I need is for it just to be activate.
How can I control this? The JS I'm aiming for the equivilent of this:
exports.activate = function() { core.print("activating"); }
This isn't currently possible but I worked around it with a wrapper:
var extension = require('./dartvsjs/extension.js');
exports.activate = extension.__lib__extension.activate;
exports.deactivate = extension.__lib__extension.deactivate;
I want to make a basic example Firefox add-on using js-ctype. First, I made a .dll file with a simple C code:
#include "stdio.h"
extern "C"
{
__declspec(dllexport) int add(int a, int b) { return a + b; }
}
The library file is fine. I tested it in another project.
I load it by js-ctypes code:
var {Cu , Cc, Ci} = require("chrome");
Cu.import("resource://gre/modules/ctypes.jsm", null);
Cu.import("resource://gre/modules/Services.jsm");
var self = require("sdk/self");
var prompts = Cc["#mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
var dataUrl = self.data.url("Js-CtypeLib.dll");
dataUrl = Services.io.newURI(dataUrl,null,null).QueryInterface(Ci.nsIFileURL).file.path;
var lib, add;
try{
console.log("Load library");
lib = ctypes.open("Js-CtypeLib.dll");
try{
declareFunc();
}
catch(e){
console.log("Error declare function");
}
}
catch(e){
console.log("Error load Library!");
}
function declareFunc(){
add = lib.declare("add", ctypes.default_abi, ctypes.int, ctypes.int, ctypes.int);
}
function test(){
var rs = add(4,2);
prompts.alert(null, "Result: ", rs);
lib.close();
}
exports.test = test;
and then, I call support.js file by index.js
var buttons = require('sdk/ui/button/action');
var tabs = require("sdk/tabs");
var support = require("./support.js");
var button = buttons.ActionButton({
id: "mozilla-link",
label: "Visit Mozilla",
icon: {
"16": "./images/icon-16.png",
"32": "./images/icon-32.png",
"64": "./images/icon-64.png"
},
onClick: handleClick}
);
function handleClick(state) {
support.test();
}
Finally, in cmd, I run it and get:
Component returned failure code: 0x80004002 (NS_NOINTERFACE) [nsIFileURL.file]
Full error text:
You need to mark your addon as "unpacked" in the package.json. Then you must use a file:// uri in the call to ctypes.open(file_uri_here).
To get a file uri of a file in your addon you would do this:
Components.utils.import("resource://gre/modules/Services.jsm");
var cr = Components.classes['#mozilla.org/chrome/chrome-registry;1'].getService(Components.interfaces.nsIChromeRegistry);
var chromeURI_myLib = Services.io.newURI('chrome://youraddon/content/mySubFolder/myCFunctionsForUnix.so', 'UTF-8', null);
var localFile_myLib = cr.convertChromeURL(chromeURI_myLib);
var jarPath_myLib = localFile_myLib.spec; // "jar:file:///C:/Users/Vayeate/AppData/Roaming/Mozilla/Firefox/Profiles/aecgxse.Unnamed%20Profile%201/extensions/youraddon#jetpack.xpi!/mySubFolder/myCFunctionsForUnix.so"
var filePath_myLib = localFilemyLib.path;
ctypes.open(filePath_myLib);