Using Grunt and Uglify to version control - javascript

I have a bunch of modules described in the following document tree:
.
├── Gruntfile.js
├── build
└── src
└── app
├── Render
│   ├── api
│   │   ├── common.js
│   │   ├── v1.js
│   │   └── v2.js
│   └── module.json
└── User
├── api
│   ├── common.js
│   ├── v1.js
│   └── v2.js
└── module.json
Where /src/app/Render/ and /src/app/User/ are both considered modules.
Inside the Gruntfile.js I wish to declare a list of included modules and default version like so:
var modules=["Render", "User"];
var version = 2;
Using this information I would like to traverse each of the modules folders, and uglify to package files in ./api/ including anything that matches the regular expression /^v[version]\./ (version refers to the variable and not a string literal) and omitting anything that matches the regular expression /^v(?!version\.)[0-9]+\./, then uglify them and store the file in /build/app/{{Module}}/api.js.
For example if version=2 is given I would like to end up with the following structure:
...
├── build
│ └── app
│ ├── Render
... │   └── api.js // /src/app/Render/api/v2.js + /src/app/Render/api/common.js
│  
└── User
└── api.js // /src/app/User/api/v2.js + /src/app/User/api/common.js
I will allow the user to run the task with a shell flag like so: grunt deploy --v=2 which would override the explicit var version = 2;
The issue is I do not get how to iterate over my array during a task and select the files I want (I've seen globbing but it doesn't seem advanced enough to select the files I want) and perform a separate uglify operation on each. I would really appreciate some advice.

One thing that people ignore so often is that you have the full power of Node.js in your Gruntfile.
var modules=["Render", "User"];
var version = grunt.option('version', 2);
var _ = require('underscore');
var fs = require('fs');
grunt.initConfig({
uglify: _.reduce(modules, function(obj, module){
obj[module] = {
files: {},
options: {
// Add your options here
}
};
obj[module].files['build/app/'+module+'/api.js'] =
_.chain(fs.readdirSync('./src/app/'+module+'/api'))
.filter(function(filename){
// Check against your regular expression here
})
.map(function(filename){
return './src/app/'+module+'/api/'+filename
})
.value();
return obj;
}, {});
})

Related

Parcel creates a new hashed file after updating a dynamically imported module

I'm using the verion 2.7 of Parcel for bundling my client side javascript. I have a index.ts where I group all my code. In some cases I have to use dynamic import statements:
example:
const { Menu } = await import('./Menu');
The issue that I can't solve: after each update on Menu.ts, Parcel creates a newly hashed Menu.[hash].js file instead of updating it.
npm run watch:js:
"watch:js": "parcel watch --no-hmr ./public/ts/index.ts --dist-dir ./public/js --public-url ./"
public folder structure:
.
└── public/
├── [...]
├── js/
│ ├── index.js
│ ├── index.js.map
│ ├── Menu.[hash-1].ts **! that's an issue !**
│ └── Menu.[hash-2].ts **! that's an issue !**
└── ts/
├── [...]
├── index.ts
└── Menu.ts

Addon - unable to add module in content_script for firefox addon

Below is the project structure of a addon I'm trying to develop.
.
├── sc_back.js
├── sc_cont.js
├── icons
│   ├── addon
│   │   ├── icon-48.png
│   │   └── icon-96.png
│   └── context
│   ├── d-16.png
│   ├── d-32.png
│   ├── e-16.png
│   └── e-32.png
├── manifest.json
├── modules
│   └── sc_de.js
└── popup
├── action.css
├── action.html
└── action.js
There is some JS code that is redundant between content script sc_cont.js and popup action script in popup/action.js so I decided to move that redundant part into a separate folder at modules/sc_de.js.
I added below lines at my content_script and at module script:
//sc_cont.js
import { xyz } from './modules/sc_de.js'
//modules/sc_de.js
export const xyz = {...}
I tried adding the modules script in manifest.json in the content_script array but it's not working. Haven't tried in web_accessible_resources as this is not supposed to be accessible from the DOM.
Problem is when I launch the addon debugger, it shows the following error:
SyntaxError: import declarations may only appear at top level of a module
SyntaxError: export declarations may only appear at top level of a module
How do I resolve these errors to make the addon work? Also, do I need to do anything special in case of popup/action.js as well?

Is there a way to rearrange JavaScript modules generated by the TypeScript compiler?

I have a TypeScript project, and the project structure is organized not unlike a typical Maven Java project. Below is more or less what the project structure looks like.
.
├── gulpfile.js
├── index.html
├── package.json
├── src
│   ├── entity
│   │   ├── car.ts
│   │   ├── animal.ts
│   └── sevice
│   ├── dao
│   │   ├── cardao.ts
│   │   ├── animaldao.ts
│   └── validator
│   ├── carvalidator.ts
│   └── animalvalidator.ts
├── test
│   ├── entity
│   │   ├── car.spec.ts
│   │   ├── animal.spec.ts
│   └── service
│   └── dao
│   ├── carvalidator.spec.ts
│   └── animalvalidator.spec.ts
├── tsconfig.json
└── webpack.config.js
I am able to generate a single *.js file for commonjs/webpack, system, and amd.
for commonjs/webpack, I use tsc + tsconfig.json and then webpack + webpack.config.js to generate a single file, bundle.js.
for system, I simply use the gulp-typescript task with module set to system to generate a single file, lib-system.js.
for amd, again, I use gulp-typescript with module set to amd to generate a single file, lib-amd.js.
However, after I load these single *.js files into the browser (with webpack I just use <script> tags and with the other I use SystemJS), I noticed that I have to instantiate my objects as follows.
var c = new car.Car('chevy', 'traverse', 2017);
var a = new animal.Animal('cat');
I don't like the fact that I am repeating myself in the code car.Car or animal.Animal. Is there a way to make it so that I can do the following without altering the project structure?
var c = new entity.Car('chevy', 'traverse', 2017);
var a = new entity.Animal('cat');
Of course I can just create a file, entity.ts and define both Car and Animal (or all entities, which there are a lot) in that one file. But that seems rather silly to me to have one long file with a lot of classes just to group the modules logically together.
I ventured into naively merging all the *.ts files into one uber ts file, but that doesn't really work because
there's a lot of imports, and you'd have to remove them (I don't know if gulp-concat can do this operation or if I need another package piped into the process to do so)
sub-classes must be defined after super-classes (as gulp-concat doesn't care about this rule when it concatenates files)
So my question is if is possible to logically group my classes (by function, e.g. entity, dao, validator, etc...) into modules instead of the default grouping (by files, one file is actually one module, I believe)?
I would expect some tools to make this possible, haven't found any solutions yet.
One solution is indeed to create a module for grouping, src/entity.ts, and re-export classes from it:
export { Car } from './entity/car';
export { Animal } from './entity/animal';
Another possibility is to use rollup.js which seems to be capable of combining several compiled modules into one, but it's for javascript only, and I don't have any experience with it.

Gulp. Compile all .jade files when child (_*.jade) included

I have next structure:
jade
├── _skeleton.jade
├── _header.jade
├── _footer.jade
|
├── includes
│ └── _include-on-index.jade
│ └── _include-on-page-1.jade
│ └── _include-on-all-pages.jade
|
├── pages
│ └── index.jade
│ └── page-1.jade
│ └── page-2.jade
│ └── page-3.jade
And I need to setup jade compile, like some apps, (for example Prepros).
It means that if I edit page-3.jade I need compile only page-3.jade, if I edit file that start with _.jade, I don`t need compile exectly this _.jade file like html, but I need to compile all .jade files that included this _*.jade file
For example when I edit file _header.jade, I need compile all files that included _header.jade, if I edit _include-on-index.jade I need to compile file without _ that included _include-on-index.jade
I`m trying to do this with module gulp-jade-find-affected, but it works incorrect, and it compile files that start with _*.jade as html.
Here is my gulpfile.js:
var gulp = require('gulp'),
jade = require('gulp-jade'),
watch = require('gulp-watch'),
affected = require('gulp-jade-find-affected');
gulp.task('watch-jade', function () {
'!sources/jade/_*.jade'
watch('sources/jade/*.jade')
.pipe(affected())
.pipe(jade())
.pipe(gulp.dest('site'));
});
gulp.task('default', ['watch-jade']);
Maybe someone have this gulp task and can help me ?

Including/excluding globs for gulp.src

I'm trying to setup a glob array for my javascript concat build task in gulp. The directory structure looks as follows:
├── about
│ └── about.js
├── assets
├── contact
├── core
│ ├── navbar
│ │ ├── navbar.js
│ │ └── navbar.test.js
│ ├── routing.js
│ ├── routing.test.js
│ ├── utils.js
│ └── utils.test.js
├── generated
│ ├── footer.js
│ ├── header.js
│ └── templates.js
├── home
├── app.js
└── config.js
The order of the files is important:
generated/header.js
app.js
any of the *.js files, except those here below
generated/templates.js
generated/footer.js
I've wildly tried all kinds of wildcards combination, but the globbing isn't strong with me.
var inputFiles = [
'generated/header.js',
'app.js',
'!(generated)**/*.js', // <=---- ???
'generated/templates.js',
'generated/footer.js',
'!**/*.test.js'
];
So how do I include all *.js files except those from a subdirectory?
Thanks.
The best I came up with:
var gulp = require('gulp');
var tap = require('gulp-tap');
gulp.task('default', function() {
return gulp.src([
'generated/header.js',
'app.js',
'*.js',
'./!(generated)/**/*.js', // <- All subdirs except 'generated'
'generated/{templates,footer}.js',
'!**/*.test.js',
'!node_modules/**'
]).pipe(tap(function(file) {
console.log(file.path);
}));
});
Running it:
∴ glob-test gulp
[20:07:51] Using gulpfile ~/Desktop/glob-test/gulpfile.js
[20:07:51] Starting 'default'...
/Users/heikki/Desktop/glob-test/generated/header.js
/Users/heikki/Desktop/glob-test/app.js
/Users/heikki/Desktop/glob-test/config.js
/Users/heikki/Desktop/glob-test/gulpfile.js
/Users/heikki/Desktop/glob-test/about/about.js
/Users/heikki/Desktop/glob-test/core/routing.js
/Users/heikki/Desktop/glob-test/core/utils.js
/Users/heikki/Desktop/glob-test/core/navbar/navbar.js
/Users/heikki/Desktop/glob-test/generated/templates.js
/Users/heikki/Desktop/glob-test/generated/footer.js
[20:07:51] Finished 'default' after 326 ms
The main trick is avoiding the "!" character at the beginning of glob when including files.
https://github.com/isaacs/minimatch#comparisons-to-other-fnmatchglob-implementations
"If the pattern starts with a ! character, then it is negated."
ps. Placement of the negated globs doesn't matter. They are always moved to the end behind the scenes.

Categories