I am trying to prepend Javascript to a javascript file using a babel plugin. This is my current babel plugin.
const babel = require("#babel/core")
module.exports = () => {
return {
visitor: {
Program: {
enter: (path, state) => {
const options = state.opts
const file = state.file
if (!options.accept(file.opts.filename)) return
path.node.body.unshift(
babel.parse(options.prepend).program.body[0]
)
}
}
}
}
}
This code does work but it does not prepend at the actual top of the file. Here is an example of where it prepends:
Is there any way to change this plugin to actually prepend the javascript at the top?
Related
I have made an extension that opens a file dialog. What I would like to do is after the file is selected, I want a python file to run. What I need is the VS Code command to run a file (or perhaps a python file specifically?).
here is a working example where the command I use is a command that comments the selected line in the currently active editor. It works perfectly so I know this structure is generally correct. I just need the right command to replace the comment line command.
below is the code in questions with the working command I mentioned above. I found it using this resource: where I found the comment line command
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
const { ChildProcess } = require('child_process');
const vscode = require('vscode');
const { execFile } = require('node:child_process');
const { stdout, stderr } = require('process');
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
/**
* #param {vscode.ExtensionContext} context
*/
function activate(context) {
let disposable = vscode.commands.registerCommand('fileDialog.openFile', function () {
const options = {
canSelectMany: false,
openLabel: 'Open'
};
vscode.window.showOpenDialog(options).then(fileUri => {
if (fileUri && fileUri[0]) {
console.log('Selected file: ' + fileUri[0].fsPath);
vscode.commands.executeCommand('python.execInInterminal');
}
});
});
context.subscriptions.push(disposable);
}
// this method is called when your extension is deactivated
function deactivate() {}
module.exports = {
activate,
deactivate
}
You can go for child_process' exec or spawn if you only need to run the Python script(s).
If you really prefer to rely on the Python extension, then you'll need to at least feed the script's Uri into the executeCommand's argument - its the 2nd part of what you found.
function activate(context) {
let disposable = vscode.commands.registerCommand('fileDialog.openFile', function () {
const options = {
canSelectMany: false,
openLabel: 'Open',
filters: {
'Python script': ['py']
}
};
vscode.window.showOpenDialog(options).then((fileUris) => {
// This will always get an array of Uris regardless of canSelectMany being false
fileUris?.forEach(async (fileUri) => {
console.log(`Selected file: ${fileUri.fsPath}`);
await vscode.commands.executeCommand('python.execInInterminal', fileUri);
});
});
});
context.subscriptions.push(disposable);
}
If you want to handle more things, you can refer to the thenable unittest code they included in the repo:
https://github.com/microsoft/vscode-python/blob/main/src/test/smoke/runInTerminal.smoke.test.ts#L46-L48
I need to write a function for the gulp.
The function should:
1. Open file (style.min.css)
2. Find all lines with the given text (img/sprite.png)
3. Replace all found lines with (../img/sprite.png)
To simplify the task, I include a plugin (replace-in-file)
I am not good at Node.js but I tried...
Please help me make it right.
If you want you can show how to do this without using a plugin (replace-in-file).
But you can also use the plugin...
const build = ('build/')
const replace = require('replace-in-file')
const config = {
build: {
style: build + 'css'
}
}
function fixSprites() {
const results = replace.sync({
files: config.build.style + '/style.min.css',
from: 'img/sprite.png',
to: '../img/sprite.png',
countMatches: true,
})
return src(config.build.style + '/style.min.css')
.pipe(replace(results))
}
exports.fixSprites = fixSprites()
I used a plugin 'replace-in-file'!
This is the out of the box gulp solution
Replace all lines of a similar type with others.
Example: replace img/sprite.png with ../img/sprite.png
const { series } = require('gulp')
const replace = require('replace-in-file')
function updateRedirects(done) {
replace({
files: 'build/css/style.min.css',
from: /img\/sprite.png/g, // img/sprite.png – Replace this.
to: '../img/sprite.png', // ../img/sprite.png – Replace with this.
countMatches: true,
}, done)
}
exports.build = series(updateRedirects) // Start
I'm trying to update the svg-chunk-webpack-plugin from webpack v4 to v5. The plugin used the compilation object and needs a flat list of file dependencies filtered by entry point to extract all SVGs for each entry points.
Example of a nested dependency tree with an entry point app-a
- app-a.js
- svg1.svg
- module1.js
- svg2.svg
- svg3.svg
- module2.js
- svg4.svg
- svg5.svg
With webpack v4, the following code works and returns an array of all SVG files used by each entry points
const path = require('path');
function getSvgsDependenciesByEntrypoint(entryName) {
let listSvgs = [];
compilation.entrypoints.get(entryName).chunks.forEach((chunk) => {
chunk.getModules().forEach((module) => {
module.buildInfo &&
module.buildInfo.fileDependencies &&
module.buildInfo.fileDependencies.forEach((filepath) => {
const extension = path.extname(filepath).substr(1);
if (extension === 'svg') {
listSvgs.push(filepath);
}
});
});
});
return listSvgs;
}
const svgs = getSvgsDependenciesByEntrypoint('app-a');
console.log(svgs) // ["svg1.svg", "svg2.svg", "svg3.svg", "svg4.svg", "svg5.svg"]
With webpack v5, I've tried the following code which produce different results between development and production build.
const path = require('path');
function getSvgsDependenciesByEntrypoint(entryName) {
let listSvgsDependencies = [];
compilation.entrypoints.get(entryName).chunks.forEach((chunk) => {
compilation.chunkGraph.getChunkModules(chunk).forEach((module) => {
module.dependencies.forEach((dependency) => {
const extension = path.extname(dependency.userRequest).substr(1);
if (extension === 'svg') {
const moduleDependency = compilation.moduleGraph.getModule(dependency);
listSvgsDependencies.push(moduleDependency);
}
});
});
});
return listSvgsDependencies;
}
In development build
const svgs = getSvgsDependenciesByEntrypoint('app-a');
console.log(svgs) // ["svg1.svg", "svg2.svg", "svg3.svg", "svg4.svg", "svg5.svg"]
In production build
const svgs = getSvgsDependenciesByEntrypoint('app-a');
console.log(svgs) // ["svg1.svg"]
Nested dependencies are not find with the production build
I fixed the bug with the webpack team on issue #12202.
This behavior is related to the side effects of the module. The webpack release v5.10.3 includes a fix which allows to manually specify the module has side effects. You could do that either in module rules or within the loader directly.
I'm trying to build a function in NodeJS which recursively check whether it is file or directory using fs library to infinitely deep sub-directories, my code is something like this:
function generateComponents(path) {
fs.readdirSync(path).forEach((file) => {
if(fs.existsSync(file) && fs.lstatSync(file).isDirectory()) {
generateComponents(path+'/'+file);
}
else {
//Do some code
}
});
}
It works for first folder/directory but when it goes for next directory it accepts as files and condition goes into else part. Am I doing something wrong?
One problem is that file in your code is JUST a filename. To recurse you have to recombine the filename with the path in order to call generateComponents in a directory that's different than the original path. That includes when you call fs.existsSync() and fs.lstatSync():
const path = require('path');
function generateComponents(dir) {
fs.readdirSync(dir).forEach((file) => {
let fullPath = path.join(dir, file);
if (fs.lstatSync(fullPath).isDirectory()) {
console.log(`directory: ${fullPath}`)
generateComponents(fullPath);
} else {
console.log(`filename: ${fullPath}`)
//Do some code
}
});
}
FYI, you should also use the withFileTypes option for fs.readdirSync() as that will save you the fs.lstatSync() call and the fs.existsSync() call is entirely unnecessary. fs.readdirSync() just told you the file was there, you don't have to check if it's there again.
That simplified version using withFileTypes would look like this:
const path = require('path');
function generateComponents(dir) {
fs.readdirSync(dir, {withFileTypes: true}).forEach((entry) => {
let fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
console.log(`directory: ${fullPath}`)
generateComponents(fullPath);
} else if (entry.isFile()) {
//Do some code with fullPath file
console.log(`filename: ${fullPath}`)
} else {
// apparently there are some other things that could be here
// like a symlink, so this is defensive coding
console.log(`unexpected type: ${fullPath}`);
}
});
}
I am working on a browserify transform and I am passing in options.
//excerpt from package.json of my application that is using my transform and extension
"browserify": {
"transform": [
["mytransform", {"extensions": ["my-extension"] } ]
]
}
The transform is working and is called on the first file and then on files depended on by that file. The problem I am having is that I am losing the options.
In my transform I have
module.exports = function (file, options) {
console.log('processing? ', file, options);
options = options || {};
options.extensions = options.extensions || [];
var extensions = options.extensions.map(function(extensionId){
return require(extensionId)();
}),
data = '';
var stream = through(write, end);
return stream;
function write(buf) { data += buf; }
function end() {
var out = processFile(extensions, file, data);
stream.queue(out || data);
stream.queue(null);
}
};
The following is the output. The options are there for the first file, but then nothing in the second file
processing? /path/to/cascadingAmdDepWithPlugin.js { extensions: [ 'my-extension' ]}
processing? /path/to/node_modules/dojo/number.js { }
How do I get my options to carry through to all files being handled by my transform?
Things are working as expected. I didn't carefully read the documentation carefully enough. Transforms aren't applied to files within node_modules. Solutions are to either specify the transform as global or update package.json of the project within node_modules. Once I did either of those things, my code worked as expected.