Ah, I see, that’s exactly my approach
Hi guys,
in “All-In-Packages” I attached all my helpers, classes and toolkits to a global namespace, p.e. MyApp.*
.
Right now I have my app itself running well in 1.3 WITH my global-namespace, BUT there is a BUT:
Within tests I am running into problems when trying to export/import like import {MyApp.ClassName.function} from './lib/class.js'
.
What do you guys recon to do? What is best-practise?
That syntax is invalid, only single names can be imported:
import {MyApp} from './lib/class.js';
// Destructure
let {function} = MyApp.ClassName;
function();
Yeah - so you recon to keep the global app-namespace and use destructure strategy?
Hmm, well I’d actually recommend to make all of your helpers, classes & toolkits standalone modules which makes them more re-usable.
Ideally default exports should be used instead of named ones and each module should have a single purpose
It took me two weeks to convert my main app from “all in packages” to “all in modules”.
Now i have started to rewrite it from “all Blaze” to all React/Redux/Mantra. I fear it will take me two years !
Damn… I thought I had it covered by making my Namspace work with modules - I basically kept my app-folders and have a index.js in each importing the files.
BUT now I am converting unit-tests and this whole “passing thru” of the “MyApp.”-Namespace starts to feel like abusing the modules idea. Unforunatly when keeping the Namespace you end up writing this in EVERY FILE: (especially when you start working on unit tests)
import { MyApp } from '../00_namespace.js'
// ... code
export { MyApp }
Plus Unit-Tests (meaning NOT having the index.js file or a full-app-mode available) forces you to implement imports/exports in EVERY SINGLE file, spinning a major net of imports/exports.
I guess I should do it right and get rid of my “MyApp.”-Namespace by a magor find/replaceby operation.
@vjau: how did you do it? Is your namespace still alive or did you get rid of it?
I didn’t use a namespace in the first place, sorry. I had tried, but found out it was not needed with a “all in packages” approach.
Ah I see. Thanks for the info.
Before the modules refactoring ?
Each “part” of the app had its own package, including template, template helpers,and business logic.
Refactoring it to modules, i used a folder for each package.
Now i’m refactoring to Mantra/Redux/React, but it’s more a full rewrite that a simple refactoring, only the div/css structure is kept.
This is the folder structure that I plan to keep:
/client/main.js // load import/startup/client (following meteor guide)
/server/main.js // load import/startup/server (following meteor guide)
/imports
/imports/startup/client // simply includes /imports/app/application
/imports/startup/server // simply includes /imports/app/application
/imports/usecases/usecase1/index.js (import files in usecase)
/imports/usecases/usecase1/...
/imports/usecases/usecase2/index.js (import files in usecase)
/imports/usecases/usecase2/...
/imports/usecases/usecase3/index.js (import files in usecase)
/imports/usecases/usecase3/...
/imports/app/application // import ALL usecases and BUNDLE them
What do you guys think of that?
How would you guys approach loading the main-application ONLY for logged in users? This should be possible now with modules, right?
I just want to note that Telescope still uses the “all-in-packages” approach (because I want people to be able to meteor add
or meteor remove
various features of the app) and it works just fine with 1.3. The best part is that I can avoid addFiles
most of the time since you don’t need to do it when you’re import
ing files inside a package.
usecases > application > startup/client & server
Wouldn’t this import your code to both? I think you should omit the extra application importer. Can your usecases go directly under /imports?
Unfortunately, no. It enables lazy evaluation but not lazy/incremental loading/code splitting. That would be a job for a module loader like SystemJS (or webpack)
With “both” - do you mean client & server, meaning that code might end up on both client and server?
My application index.js looks like
import '/imports/usecase1'
import '/imports/usecase2'
// ...
then in my “imports/usecase1/index.js” I do something like
import '/imports/common/' // common stuff for all applications
// import files within "./lib/*"
import './lib/collection.js' // use-case specific collection
// ..
// CLIENT FILES (remember to always load .html first)
// .. we need to use ``require`` here as it is conditional!
if (Meteor.isClient) {
require ( './client/router.js' )
require ( './client/template.html' )
require ( './client/template.js' )
}
// SERVER FILES
// .. we need to use ``require`` here as it is conditional!
if (Meteor.isServer) {
require( './server/publications_and_allows.js' )
}
What do you think?
Ah I see - well, the good news is that migrating to modules lays the ground for using SystemJS.
The remaining questions is: With SystemJS: could we actually “protect” our code, so that only registered users see it?
Yeah, but not if you’ve split the code in your usecases into client/server folders, which you have.
I suggest sticking to the import syntax (it’s future-proof!)
Then you can either:
- Create separate index.js files in each usecase for client/server
// imports/startup/client
import '/imports/usecases/usecase/client/index';
- Or move environment-specific code under it’s parent folder
// imports/startup/client
import '/imports/client/usecases/usecase/index';
Yep, you can choose which code parts to load, and when.