Is there a way to 'build' my code depending on .env variables? - javascript

I'm trying to optimize my website. I would like to create the thinnest build possible.
I have a .env file containing
REACT_APP_ENV = DEV
Here is an exemple of what I want to reduce :
if (REACT_APP_ENV === "DEV) {
// DO SOMETHING A
} else {
// DO SOMETHING B
}
I would like to reduce it to :
// DO SOMETHING A
Is there a way to create a reduced build like this ?
We already know that REACT_APP_ENV === DEV when building, so it seems possible to me that we can simplify this code.
Currently, I am using webpack with babel to build.
If you have any clues, I'd appreciate to see them.
Thank you for reading

Related

Override require to start from root and check node modules without changing it's name

I'm trying to share my client and server code and I want a tidy way of requiring my dependencies.
I'm currently using webpack as my build tool and I've set it to resolve to my assets/js folder so my dependencies for the client look something like this:
require('validators/login.js');
I'd like to share the exact same code across the server, but I don't want to put if statements in to check if it's the server or client that's doing the requiring so I can do something like
if server
rootRequire..
else
require
What i'd like is for the server to use require like the client does and start from the root directory, but I also don't want to strip it of its functionality to search the node_modules folder if it doesn't return a result.
I also want this done without placing all my code in the node_modules folder.
Does anyone have some good suggestions for how to override require properly? I've read most of the hacky solutions like using symlinks or placing things in node_modules and I'm not looking for those answers, I'd like something that is clean and actually overrides require properly.
I think I've come up with a solution I'm reasonably happy with, figured I'd share it with anyone who else needed an answer.
var module = require('module');
var baseRequire = module.prototype.require;
module.prototype.require = function()
{
// Add any extra paths here...
var extraPaths = [
__dirname
];
for (var i = 0, len = extraPaths.length; i < len; i++) {
if (this.paths.indexOf(extraPaths[i]) == -1) {
this.paths.push(extraPaths[i])
}
}
return baseRequire.apply(this, arguments);
};

Combine two Javascript directories into two single, separate files

The project I'm working on is using combineJS from this gradle plugin in its gradle build. What it does is combine the contents of a directory, in this case topsoil_js, into a single javascript file. I would like to do the same, but with the contents of a different directory, plots_js, into a different single file.
The current code looks like this:
javascript.source {
topsoil {
js {
srcDir 'src/main/resources/org/cirdles/topsoil/plot/topsoil_js'
include '*.js'
}
}
plots {
js {
srcDir 'src/main/resources/org/cirdles/topsoil/plot/plots_js'
include '*js'
}
}
}
combineJs {
source = javascript.source.topsoil.js.files
dest = file("${project.buildDir}/resources/main/org/cirdles/topsoil/plot/topsoil.js")
}
I've tried adding an identical combineJs statement to combine plots_js, like so:
combineJs {
source = javascript.source.plots.js.files
dest = file("${project.buildDir}/resources/main/org/cirdles/topsoil/plot/plots.js")
}
The problem is that source and dest get overwritten, so only the last combineJs you call actually combines a file. I'm relatively new to gradle, so I'm not actually sure how the rest of the project consumes these variables. Are they keywords that gradle knows to look for, or are they arbitrary?
Most importantly: does anyone have suggestions on how to combine both sets of files?
EDIT: I also tried following the instructions in this documentation for the plugin, which tells me to format it like so:
task combineTopsoilJs(type: com.eriwen.gradle.js.tasks.CombineJsTask) {
source = javascript.source.topsoil.js.files
dest = file("${project.buildDir}/resources/main/org/cirdles/topsoil/plot/topsoil.js")
}
task combinePlotJs(type: com.eriwen.gradle.js.tasks.CombineJsTask) {
source = javascript.source.plots.js.files
dest = file("${project.buildDir}/resources/main/org/cirdles/topsoil/plot/BasicPlot.js")
}
But this format isn't working either, just throwing an error I'm having trouble tracking down.

Using webpack to build a dependency before compiling the build

I'm using inline styles & my theme comes from a file called themes.json, which I create & inject into my build folder before calling webpack. I'd like webpack to handle this, too.
My first attempt was to use a plugin:
compiler.plugin('compilation', async(compilation, callback) => {
const themes = {}; // empty for this example
compilation.assets['themes.json'] = {
source: function() {
return themes;
},
size: function() {
return themes.length;
}
};
callback();
}
However, since plugins run async or parallel, I come across a race condition where my index.js that has a const themes = require('../build/themes.json') is trying to require something before it exists.
How can I make sure themes.json exists and is useable within my build? I see 3 possibilities:
There's a way to run plugins in serial that I don't know about
I somehow use a loader to perform this
I write a plugin that looks for require('../build/themes.json') and when it finds it, it creates & injects the themes.
Any help on the right way to do this?

JavaScript Module pattern files concatenation in a one file and using their functions

I write different files under JavaScript Module Patern like this:
file 1.js
var Module = (function (module) {
module.function = function () {
console.log(this.thirdFunction) // This is my issue. I cannot access the function from the third file because it is concatenated in a way that the function still not exist.
};
return module;
}(Module || {}));
some-folder/file 2.js
var Module = (function (module) {
module.somethingElse = function () {
};
return module;
}(Module || {}));
whatever/file 3.js
var Module = (function (module) {
module.thirdFunction = function () {
};
}(Module || {}));
I put all these files in different directories, names in a different time.
Then I am using concatenating tool to have one file and then I use it in my html file. But I am facing trouble that I cannot resolve.
To have all these working, I have to include them in a specific way and order to call functions from whatever I need and to re-order files when something is not yet defined/created in the returned final object. If I have 100 files and folders it will be a trouble for me again.
Do I understand this right: http://gruntjs.com/configuring-tasks#globbing-patterns
that I have manually to order files, folders and everything in my grunt tasks?
I do not want to use AMD tools, just plain JavaScript files and some approach to hack the order requirements. If there is no any easy idea for me to you, I would try the AMD tools like require.js but I am not sure if these kind of tools can help with this lame problem.
I would appreciate some grunt tool, some files/folders names conventions, anything that would not force me to install more and more tools.
Thank you in advance!
Another thing that bothers me is the following:
If I want to isolate code but I do not have to return object property in the final object, is it alright to do something like this:
file 4.js
var Module = (function (module) {
var someThing = Module.somethingElse() // from file 2.js
and then using someThing here for clicking, DOM rendering, etc, etc
}(Module || {}));
Is it stupid to stick to the same var Module conventions for files where I actually do not return anything? I just think of way how to avoid the object name and using this again
Indeed, AMD tools were created just for this kind of problem. However you can work around this to some extent with grunt. You could simply organize the files that need to go first into a folder and list them out in the order you want, and then have another folder containing all files who's order doesn't matter, which will include everything.
'js/main/First.js',
'js/main/Second.js',
'js/rest/*.js'
No matter what you choose for this project, you might want to look into Require.js or Browserify for future work.

How Do You Get Around Javascript File Order Using Gulp Or A Javascript Framework?

I'm using gulp to build a single javascript file with gulp-concat and gulp-uglify.
Original Files
//File 1
var Proj = Proj || {};
//File 2
Proj.Main = (function() {
var Method = function(){ /*Code*/ };
return { "Method":Method };
})();
//File 3
Proj.Page = (function() {
var Method = Proj.Main.Method;
return { "Method":Method };
})();
Gulp returns a bad minified file because these files are being concatenated in the wrong order. I know I can specify the order in .src([]) but I don't want to maintain the array as I add javascript files.
Is there a way to create references to these "namespaces" without having to worry about the order of the files concatenated? Or, is there a way for gulp to handle concatenation with the knowledge of these namespaces auto-magically?
EDIT:
I know I can specify the file order inside the .src([]). I want to develop without having to worry about the file order, whether it be through a gulp package or a javascript framework. Thank you for responses that help but I need a definitive "No. You cannot do this." or "Yes. Here's how..." to mark the thread as answered.
Well, one option is to try gulp-order.
Also, check out this answer to "gulp concat scripts in order?".
Basically, it mentions what you already said, about having to explicitly name the files in the order you want them to come in. I know you don't want to do that, but how else would gulp know which order you want your files in?
One thing worth pointing out, though, is that you have a group of files where the order doesn't matter, and then, say, 2 files where the order does matter, you can do something like this:
gulp.src([
'utils/*.js',
'utils/some-service.js',
'utils/something-that-depends-on-some-service'
])
gulp-concat doesn't repeat files, so everything that's not some-service.js or something-that-depends-on-some-service.js will get concatenated first, and then the last two files will be concatenated in the proper order.
Since it hasn't been mentioned, implementing webpack or browserify will absolutely solve this problem without implementing some sort of hacky feeling solution.
Here is a simple example of how to use it:
var source = require('vinyl-source-stream'), //<--this is the key
browserify = require('browserify');
function buildEverything(){
return browserify({
//do your config here
entries: './src/js/index.js',
})
.bundle()
.pipe(source('index.js')) //this converts to stream
//do all processing here.
//like uglification and so on.
.pipe(gulp.dest('bundle.js'));
}
}
gulp.task('buildTask', buildEverything);
And inside your files you use require statements to indicate which files require others.

Categories