JavaScript Concatenator
I'm considering writing a JavaScript library to achieve Data Hiding under Modularization. I hope to get some inputs on whether this will be useful and what are the potential problems.
Let's me explain the problem first. What I'm trying to achieve are these:
Data Hiding
What I mean by data hiding is this kind of pattern:
!function(context) {
var privateObj = {state: 'normal'};
var privateFunc = function() {alert("I'm private")};
var toggleState = function() {privateObj.state = 'emergency'};
}(window.myNamespace);
Here, curious users will not be able to change my private variables nor invoke my private functions.
Modularization
The above works as long as everything is in one js file. But once the js file becomes too big that I would like to modularize:
first.js:
!function(context) {
var privateObj = {state: 'normal'};
var privateFunc = function() {alert("I'm private")};
}(window.myNamespace);
second.js:
!function(context) {
// This won't work. I can't access privateObj as we are not in same closure
var toggleState = function() {privateObj.state = 'emergency'};
}(window.myNamespace2);
It won't work anymore. Sure I can put toggleState
together with privateObj
but there are always the need to communicate data across modules. This is just an illustration.
Is this a real problem?
Are there really cases when we want a function to be accessible by other modules but not accessible by the public? I think yes. A straight forward example is this:
var chartDrawingMod = function() {
var drawChart = function(data) {// draw chart with data};
};
In this case, we should all agree that
Chart-related stuff should be cohesive module in itself
The method drawChart() should be invoked by my code in other modules to provide the data
We don't want the user to arbiturarily invoke my drawChart() therefore it's not desirable to make it public
The MathJax project encountered this problem. Their solution is to use a bash script to concatenate all scripts before deploy. The reason they need to do this is that first the modules are inter-dependent so they need to be inside the same file, and second the file is simply too huge to managed if combined (30k LOC). Exactly the same issue here, so I believe this is a real problem.
Proposed solution- JS Concatenator
Put them in one closure, on the fly.
Here's how I imagine it should work. In HTML I have these:
<script src="concatenator.js"></script>
<script>
Concat.concateIntoOneClosureWithContext(['/public/js/first.js', '/public/js/second.js'], window.myNamespace);
</script>
Then it should do something like this:
!function(context) {
// dump the content of '/public/js/first.js'
// dump the content of '/public/js/second.js'
}(window.myNamespace);
And first.js
and second.js
are stripped down to:
var privateObj = {state: 'normal'};
var privateFunc = function() {alert("I'm private")};
var toggleState = function() {privateObj.state = 'emergency'};
Will this work?
Will this proposed solution work? Am I missing out some important points? What are potential problems? How may I go about implementing it? Any suggestion is much appreciated!