Modify JS files using another JS file - javascript

How can I edit a JS file (containing a JSON object) using another JS file?
Example:
JS file to be edited (eslintrc.js):
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint',
sourceType: 'module'
},
env: {
browser: true
}
}
And I want to let's say add additional configuration lets say in:
env: {
browser: true,
node: true
}
I tried doing something like:
fs = require('fs');
var m = JSON.parse(fs.readFileSync('.eslintrc.js'));
console.log(m)
But of course, as expected, I am getting errors.
undefined:1
module.exports = {
^
SyntaxError: Unexpected token m in JSON at position 0
at JSON.parse (<anonymous>)
To also add, this is not the only file I need to update. There are several others that look similar in nature but not exactly the same such as:
module.exports = function (ctx) {
return {
// --> boot files are part of "main.js"
boot: [
],
css: [
'custom.scss'
]
}
}
How can I open the JS file and be able to edit the JSON object inside without distoring the actual JS file?
Thank you!

You must eliminate 'module.exports =' from eslintrc.js in order to parse it with JSON.parse function.

Related

Load a CJS module config inside another file

I'm trying to load a config inside a node module but I'm not sure which is a good practice to do it, I have this scenario:
A config my.config.js:
module.exports = {
content: [
'./src/**/*.{tsx,ts}',
],
}
Then I have a module cli.mjs is supposed to load it:
import arg from 'arg'
import { readFile } from 'fs/promises'
import path from 'path'
let configPath = './my.config.js'
const args = arg({
'--config': String,
'-c': '--config',
})
if (args['--config']) {
configPath = args['--config']
}
console.log(readFile(path.resolve(configPath), { encoding: 'utf8' }))
This will just return a simple string with my config inside, not a javascript object:
`
module.exports = {
content: [
'./src/**/*.{tsx,ts}',
],
}
`
How should I load my config in the right way?
I've saw basically everyone use configs like that in TypeScript or CJS projects, but it's hard to me see how and where they parse these configs, probably I'm missing some basic information about this?

Dynamically set script tag through Grunt based on ENV

During my Grunt build process, I would like to set the script tag in my index.html which references the Google Maps API dynamically based on process.env.NODE_ENV.
Something like:
let googleMapsUrl;
if (process.env.NODE_ENV === 'development') {
googleMapsUrl = '//maps.googleaps.com/maps/api/js?v=3.exp&libraries=visualization';
} else {
googleMapsUrl = `//maps.googleaps.com/maps/api/js?key=${process.env.GOOGLE_MAPS_API_KEY}v=3.exp&libraries=visualization`;
}
My question is how do I then insert googleMapsUrl into a script tag in index.html like so: <script src=googleMapsUrl></script>
There are many options that you could use. From simple, like grunt-replace to more advanced ones like grunt-processhtml. I will describe the first one as it’s a good option for simple tasks and requires just a simple configuration.
Using grunt-replace
grunt-replace will search for simple variable definitions like ##foo in your source files, and replace those variables with your supplied value or the returning value from a callback.
First install the plugin using npm install grunt-replace --save-dev
Then configure the task as follows:
replace: {
dist: {
options: {
patterns: [
{
match: 'gmaps',
replacement: function() {
var googleMapsUrl;
if(process.env.NODE_ENV === 'development') {
googleMapsUrl = '//maps.googleaps.com/maps/api/js?v=3.exp&libraries=visualization';
} else {
googleMapsUrl = '//maps.googleaps.com/maps/api/js?key=' + process.env.GOOGLE_MAPS_API_KEY + 'v=3.exp&libraries=visualization';
}
return googleMapsUrl;
}
}
]
},
files: [
{
expand: true,
flatten: true,
src: ['path/to/your/source/file.html'], dest: 'destination/folder/'
}
]
}
}
Load the plugin using grunt.loadNpmTasks('grunt-replace') and then add it to your build process.
On your source files just add the defined variable as your script source:
<script src="##gmaps"></script>
The task will replace ##gmaps with the returning value from the defined callback.
Hope it helps.
More about plugin can be found here.

Grunt - mongoimpot --headerlines?

I am trying to upload a CSV file using the mongoimport plugin for grunt. I am receiving the following error when running grunt:
Running "mongoimport" task
2017-03-29T18:43:57.463-0700 error validating settings: must specify --fields, --fieldFile or --headerline to import th
is file type
2017-03-29T18:43:57.464-0700 try 'mongoimport --help' for more information
The error message is pretty obvious so I adjusted my grunt task to include headerline: true
This doesn't appear to be correct as the error remains the same. After looking at their documentation for any mentioning of the --headerline property, the only thing I see is this:
collection.fields
Specify a comma separated list of field names when importing csv or tsv files that do not have field names in the first (i.e. header) line of the file.
- https://github.com/andrewkeig/grunt-mongoimport
What is the correct way using grunt to import mongodb data from a csv?
gruntfile.ts
module.exports = (grunt) => {
grunt.initConfig({
mongoimport: {
options: {
db: 'mynewdatabase',
collections: [
{
name: 'somethings',
type: 'csv',
file: 'data/test.csv',
headerline: true // <----does not work
}
]
}
}
});
//Load Plugins
grunt.loadNpmTasks('grunt-mongoimport');
//Run Tasks
grunt.registerTask('default', ['mongoimport']);
}
The csv file does have headlines and if I run the below mongo command in a terminal, it works fine:
use mynewdatabase
mongoimport --db mynewdatabase --collection somethings --type csv --headerline --file test.csv
Looking at the mongimport source code, they have the following logic:
if (collection.type === 'csv' || collection.type === 'tsv') {
if (collection.headerLine) args.push('--headerline');
}
If i'm passing the type of csv then it looks like --hearline should be getting added already so the error message doesn't seem to be aligning with what i'm seeing the code/task...
I was looking over the documentation. In their source code they have the following
if (collection.type === 'csv' || collection.type === 'tsv') {
if (collection.headerLine) args.push('--headerline');
}
This means if you pass headerLine: true and your type: 'csv' then you mongoimport will include the --headerline
module.exports = (grunt) => {
grunt.initConfig({
mongoimport: {
options: {
db: 'mynewdatabase',
collections: [
{
name: 'somethings',
type: 'csv',
file: 'data/test.csv',
headerLine: true // <----works
}
]
}
}
});
//Load Plugins
grunt.loadNpmTasks('grunt-mongoimport');
//Run Tasks
grunt.registerTask('default', ['mongoimport']);
}

Systemjs-Builder - Cannot configure properly - Bundling Typescript into a package

I want to build a quick nodejs script to package a Typescript app as SystemJS modules, a lot like what Angular2 bundles look like.
I tried different configurations but I can't seem to put my finger on it, and haven't found clear enough documentation as of yet.
Note that for this "test", I am not using Gulp or Jspm at all, just systemjs-builder for the time being (and don't plan on using jspm at all either)
Here's what my "project" looks like:
---- Project's Root
-------- index.ts // export * from './modules/index' and eventually more
-------- modules
------------ index.ts // export * from './menu/index'
------------ menu
---------------- menu.component.ts // export class
---------------- menu.service.ts // export class
I want to package this under a single file, where I will have multiple SystemRegister modules that can be consumed in an app thereafter
I tried the following without success:
var Builder = require('systemjs-builder');
// optional constructor options
// sets the baseURL and loads the configuration file
var builder = new Builder('./modules');
builder.bundle('./modules/index.ts', {
/* SystemJS Configuration Here */
baseURL: './modules',
transpiler: 'typescript',
typescriptOptions: {
"module": "system",
"emitDecoratorMetadata": true,
"experimentalDecorators": true
},
defaultExtension: 'ts',
packages: {
'modules': {
defaultExtension: 'ts'
}
}
}, 'infrastructure.js')
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.error(err);
})
First of all, the defaultExtension options doesn't seem to work at all
So when I do import {something} from 'filePath'; (without extension), it tries to load filePath, instead of filePath.ts;
Second, if I try adding the .ts extension in my imports (which I don't want to do), it complains that the code is invalid (unexpected token #, unexpected token menuItem and so forth)
Anyone have a good example or some explanations on how this is supposed to work?
Thank you
here you have an example: angular typescript skeleton
build task looks like this:
const path = require('path');
const Builder = require('jspm').Builder;
const builder = new Builder();
const packageJson = require(path.join(config.projectDir, 'package.json'));
return beginBuild()
.then(buildSFX)
.catch((err) => console.log('Build Failed', err));
function beginBuild() {
builder.reset();
return builder.loadConfig(path.join(config.projectDir, packageJson.jspm.configFile))
}
function buildSFX() {
const appName = packageJson.name;
const distFileName = `${appName}.min.js`;
const outFile = path.join(config.distDir, distFileName);
const moduleName = 'app';
const buildConfig = {
format: 'global',
minify: true,
sourceMaps: true
};
return builder.buildStatic(moduleName, outFile, buildConfig);
}
and jspm conf looks like this:
System.config({
defaultJSExtensions: true,
transpiler: "typescript",
typescriptOptions: {
"tsconfig": "src/tsconfig.json"
},
paths: {
"github:*": "vendor/jspm_packages/github/*",
"npm:*": "vendor/jspm_packages/npm/*",
"app": "src/index"
}
/// ...
}
Why do you want to bundle typescript? Bundling is a method used for optimizing the delivery of source code to the browser. The browser doesn't know typescript, it only knows javascript (unless you do on the fly transpiling).

How to enable Stylus url() rewrites

I'm trying to get stylus urls to work. I would like to convert the url('/path/to/img.png') to convert to the base64 encoded form.
I'm trying to follow the documentation here, but it's not helping me much.
I tried adding the require bit and the example functions, importing url, but not sure how to enable this thing.
How do I get this to work?
UPDATE:
Trying to use grunt-image-embed plugin.
Here is my grunt config:
imageEmbed: {
dist: {
src: [ "./public/local/css/images.css" ],
dest: "./public/prod/css/images.css",
options: {
deleteAfterEncoding : false
}
}
},
And the css contains:
#footer-social .youtube {
width: 18px;
background-image: url('/img/youtube-icon.png');
}
Which produces the error:
Warning: File C:\path\...\grunt-image-embed\tasks\lib\img\youtube-icon.png
does not exist Use --force to continue.
If I remove the background-image line it all works and goes through fine. I can't modify the paths in the css because on local we use the relative path to the actual image.
try this:
function compile(str, path) {
return stylus(str)
.define('url', stylus.url({
paths : [__dirname + '/public'],
limit : 10000
}));
}
From here:
http://bengourley.co.uk/using-stylus
It worked for me here:
https://github.com/MichaelJCole/wintersmith-stylus/blob/master/plugin.coffee
It's coffeescript, and the interesting part is this:
stylus(#_text, options)
.use(nib())
.define('url', stylus.url(
paths : [__dirname + '/public']
limit : locals.inlineSpriteMaxBytes || 0 ) )
.render (err, css) ->
if err
callback err
else
callback null, new Buffer css
I do not know how it makes no a stylus, but you can use this [1]: http://docs.emmet.io/actions/base64/
I think you'll find this grunt plugin to be exactly what you need; grunt image embed. Works for both images and fonts. From the docs:
grunt.initConfig({
imageEmbed: {
dist: {
src: [ "css/styles.css" ],
dest: "css/output.css",
options: {
deleteAfterEncoding : false
}
}
}
});

Categories