How to execute a gulp task even if the file is unchanged - javascript

EDIT: Additional addition of code for task execution
I have a question I can't answer. I need gulp to execute a stain even if the file is unchanged. Currently only when I change my source file it recreates the new destination file. But I would like it to create it even if it hasn't changed. Thank's you in advance :)
Library external : "gulp-inject-string": "^1.1.2",
// Add timestamp in cache PWA
function pwa_cache() {
return src(`${paths.pwa}/serviceworker.tmp.js`)
.pipe(inject.prepend('const CACHE_VERSION = "pwa-v-'+ new Date().getTime() +'"; \n'))
.pipe(rename('serviceworker.js'))
.pipe(dest(`${paths.js}/pwa/`,{overwrite:true}))
}
// Generate all assets
const generateAssets = parallel(
styles,
scripts,
pwa_cache,
imgCompression
)
exports.default = series(generateAssets)
exports["generate-assets"] = generateAssets

Are you maybe running this task within a gulp.watch() ? If so, you'd need to stop the watch task and re-run it.

well I proceeded differently, if it can help someone, it's the only way I found and I don't have time to find another solution.
Instead of adding I rather assign the variable in my file and then I change its value, and I no longer work on a template file but directly on the original file.
Post and link that helped me find the answer: https://eureka.ykyuen.info/2015/07/13/gulp-rewrite-source-files-instead-of-creating-new-files/, How to inject variable value into JS file from GULP, Inject variable into html via Gulp Task
gulp file :
// Add timestamp in cache PWA
function pwa_cache() {
return src(`${paths.js}/pwa/serviceworker.js`, {base: './'})
.pipe(sourcemaps.init())
.pipe(replace(new RegExp('django-pwa-v-\\d*', 's'), 'django-pwa-v-'+ new Date().getTime()))
.pipe(sourcemaps.write('./'))
.pipe(dest('./'))
}
js file :
// Cache version don't touch string assigned to the variable /
CACHE_VERSION = "django-pwa-v-1580491632502";
/////////////////////////////////////////////////////////////

Related

Update user/workspace settings from vs code extension

I am trying to update setting.json from my vs code extension and I want to add below code
"files.associations": {
"*.app": "auraComponent"
}
In other words I want to add below key value pair from extension to the users who are going to install my app
So I tried putting the below code in extension.js but it didn't update the settings.
import { ConfigurationTarget, workspace } from 'vscode';
const configuration = workspace.getConfiguration('files.associations');
configuration.update('.app', 'auraComponent', ConfigurationTarget.Global).then(() => {
// take action here
});
Could someone please suggest if I am using the right approach to update the user or workspace settings and also if the code inside extension.js would be executed automatically or not.
Update
I have added extension.js and included the js code as mentioned by mark in his answer
and update my package.json as below
"main": "./extension",
"activationEvents": [
"*"
],
If I run my extension on debug mode then it works fine but not working in real time.
The below works whether there is a pre-existing files.association setting or not. If there is already one, the new association is added to it (and so may be located somewhere other than the end of the settings file - otherwise a wholly new files.associations setting will be added to the very end of the settings.json file..
const fileConfiguration = vscode.workspace.getConfiguration('files');
const associations = fileConfiguration.get('associations');
associations['*.app'] = "auraComponent";
fileConfiguration.update('associations', associations, vscode.ConfigurationTarget.Global).then(() => {
// take action here
});
Adapted from https://stackoverflow.com/a/49566662/836330.
As explained there, what you really want to update is the associations object, that is the value to be updated. "*.app": "auraComponent is not a configuration key. files.associations is the key and there is an object {...} which is its value.

Is there a way to read JS code as part of a JS file from another JS file ? (The app uses NodeJS)

I am working on a web app using NodeJS. The concept is : the main structure, to which you add the tools you want depending on what you want in your app.
To achieve that, I want my main JS file (index.js) to read the content of another file (tool.js) as if it was part of the code.
I know I can require a module in NodeJS and call a function from it, but this isn't what I want as I don't want to put the content of the file in a function. Here is an example of what I would like to achieve :
tool.js :
// tool.js
// This executes various actions.
var web_func = require(web_funcs.js); // another module, not important
web_func.executeAction();
console.log('whatever');
index.js :
// index.js
// This is the main file
/*Here I want to call tool.js*/
The goal is to have index.js be read as this :
// index.js
// This is the main file
// tool.js
// This executes various actions.
var web_func = require(web_funcs.js); // another module, not important
web_func.executeAction();
console.log('whatever');
The reason behind this is that I want my mainframe to be easy to deploy with minimal adjustments, and everything regarding the tools to be handled in a different file to make it easier to read.
And since there are several tools and the number will probably grow, I want it to be easily set-up.
If you have any idea or solution, please let me know, as it would be of great help. I've tried looking around but didn't find anything.
EDIT : changed the title of the question for better clarity.
You can read the file first and then use the eval() method to execute the code in string.
Read the code and call eval using this sample:
my-file.js
var a = "test";
console.log(a);
Code:
var fs = require('fs');
var code = fs.readFileSync('my-file.js', 'utf8');
eval(code);
Output:
test
Edit 1:
You can also reuse the variables from the other file in this way. For example, add console.log(a) after the eval(code) line.
...
eval(code);
console.log(a);
The output will be:
test
test

How to edit an object within a very simple JS file using Node.js

Whilst this question is related to Workbox and Webpack, it does not require any prior knowledge of either library.
Background (skip if not familiar with Workbox)
I am currently utilising the InjectManifest plugin from Workbox 4.3.1 (workbox-webpack-plugin). This version of the library offers an option called manifestTransforms, but unfortunately, the transformations are not applied to assets within the webpack compilation (this is a known issue).
Whilst this has been fixed in Workbox v5+, I am unable to upgrade due to another library in my build process requiring webpack v3 (Dynamic Importing in Laravel Mix)
The reason I mention the above is because unforunately the solution is not to upgrade to workbox v5+.
The Problem
I have an auto-generated file that looks like this:
self.__precacheManifest = (self.__precacheManifest || []).concat([
{
"revision": "68cd3870a6400d76a16c",
"url": "//css/app.css"
},
// etc...
]);
I need to somehow extract the the contents of the object stored within self.__precacheManifest, apply my own transformations, and then save it back to the file.
What I have Tried...
This is as far as I have got:
// As the precached filename is hashed, we need to read the
// directory in order to find the filename. Assuming there
// are no other files called `precache-manifest`, we can assume
// it is the first value in the filtered array. There is no
// need to test if [0] has a value because if it doesn't
// this needs to throw an error
let manifest = fs
.readdirSync(path.normalize(`${__dirname}/dist/js`))
.filter(filename => filename.startsWith('precache-manifest'))[0];
require('./dist/js/' + manifest);
// This does not fire because of thrown error...
console.log(self.__precacheManifest);
This throws the following error:
self is not defined
I understand why it is throwing the error, but I have no idea how I am going to get around this because I need to somehow read the contents of the file in order to extract the object. Can anyone advise me here?
Bear in mind that once I have applied the transformations to the object, I then need to save the updated object to the file...
Since self refers to window and window does not exist in node.js a way around is needed.
One thing that should work is to define the variable self in Node's global scope and let the require statement populate the content of the variable, like this:
global['self'] = {};
require('./dist/js/' + manifest);
console.log(self.__precacheManifest);
To save the modified contents back to the file
const newPrecacheManifest = JSON.stringify(updatedArray);
fs.writeFileSync('./dist/js/' + manifest, `self.__precacheManifest = (self.__precacheManifest || []).concat(${newPrecachedManifes});`, 'utf8');

Gulp-inject says "Nothing to inject into index.html"

I'm trying to inject some files in my index, all of them concatenated and minified into a .tmp folder, as follows:
gulp.task('prep-js',['clean'], function(){
var jspath = './src/page/**/*.js';
var treatJs = gulp.src(jspath)
.pipe(plugins.concat('scripts.js'))
.pipe(plugins.uglify())
.pipe(gulp.dest('.tmp/page/js'))
});
But when I run the injection task, it says "Nothing to inject into index.html". Here's the code:
gulp.task('inject-deps', ['prep-css', 'prep-js'], function(){
//select main bower files
var bowerDep = gulp.src(plugins.mainBowerFiles(), {read: false});
//inject files
return gulp.src('./src/page/index.html')
.pipe(plugins.inject(bowerDep, {relative: true, name:'bower'}))
.pipe(plugins.inject(gulp.src('.tmp/page/js/*.js'), {name:'frontjs'}))
.pipe(plugins.inject(gulp.src('.tmp/page/css/*.css'), {name:'frontcss'}))
.pipe(gulp.dest('.tmp/page'));
});
Interesting thing, the first pipe injecting the main bower files works perfectly, but it doesn't happen to the following two.
Also, just for information, 'plugins' is a variable which is requiring my plugins.
Any idea about this issue?
You need to return the stream in your prep-js task:
gulp.task('prep-js',['clean'], function(){
var jspath = './src/page/**/*.js';
return gulp.src(jspath)
.pipe(plugins.concat('scripts.js'))
.pipe(plugins.uglify())
.pipe(gulp.dest('.tmp/page/js'))
});
Otherwise inject-deps will not wait for prep-js to finish before it runs, meaning the concatenated and uglified JS files will not be in .tmp/page/js yet.
Relevant portion of the Gulp documentation:
Note: By default, tasks run with maximum concurrency -- e.g. it launches all the tasks at once and waits for nothing. If you want to create a series where tasks run in a particular order, you need to do two things:
give it a hint to tell it when the task is done,
and give it a hint that a task depends on completion of another.

Node.js reload external file every n-minutes

I've got a question regarding loading external files in node.
Basically I'm loading an external JSON file that contains some configuration, and this file is modified by an external process every 10 minutes. How can i reload this file every 10 minutes, without restarting node?
I've tried this solution:
delete require.cache['/home/conf/myfile.json']
but some people have advised against it. Can anybody help me?
At the end I changed my code and I now use fs.readFile to load my json file, instead of using a require.
I then used node-watch to check for changes in file and reload it.
Couple options. You could just use setInterval for 10 minutes and read the file in the callback. Otherwise you could use fs.watch and trigger the reload when the file actually changes.
update based on comment
If you're using require, it will only load the file once, regardless of how many times you're requiring it and there isn't really a mechanism to invalidate a required file. You could create a wrapper around the functionality and require that instead. Your wrapper is the file you require, and it exposes a function which returns your current config. Inside that module you could create the setTimeout refresh mentioned above.
You can have a look at my module-invalidate module that allows you to invalidate a required module. The module will then be automatically reloaded on further access.
Example:
module ./myModule.js
module.invalidable = true;
var count = 0;
exports.count = function() {
return count++;
}
main module ./index.js
require('module-invalidate');
var myModule = require('./myModule.js');
console.log( myModule.count() ); // 0
console.log( myModule.count() ); // 1
setInterval(function() {
module.constructor.invalidateByExports(myModule);
console.log( myModule.count() ); // 0
console.log( myModule.count() ); // 1
}, 10*60*1000);

Categories

Resources