What is the best way to structure an Angular2 component library? - javascript

I am looking to work on an Angular2 datepicker component as if for release and inclusion in multiple projects. What is the best way to structure the project for this compared to a regular Angular2 project built with angular-cli? Are there any examples of good starter projects/seeds for such a task? Or should the component library actually be an angular2 application itself?
My initial assumption was that I could just create a standard project with angular-cli which has a single module (e.g. MyDatepickerModule) which contains a hierarchy of components forming the datepicker however I don't know if this is the best way as I don't need everything that a full application provides.
Thanks for any guidance!

I would publish the library with AoT compatibility in mind.
This means compiling the source using the ngc compiler. In the distribution package I would publish the JS source, original html/css files, d.ts typings files and the ngc generated metadata.json files.
I recommend publishing the JS source with es2015 modules since this will make your library tree shakable. I would target es5 JS, but with es2015 modules . TypeScript allows for this hybrid mode by setting module to ES2015 and target to es5 in tsconfig.json.
Publishing these files will make your library AoT compatible and Tree shakable.
This is all the consuming application needs in order to AoT compile your library into their complete application.
It's not recommended to publish TypeScript in your package since this would require the consumer to replicate your build environment (typings + TS compiler version).
You can also publish a JiT compatible umd bundle with inlined templates and css. This can be helpful since it might not be practical do AoT during development since compilation is a bit slow. The umd bundle will make it possible to use your library in a JiT based dev environment. For production though you should definitely use the AoT version.
The CLI is not ideal for publishing libraries since CLI is primarily a tool for building complete applications. They might support libraries better in the future though.

Check out https://github.com/angular/material2. A work in progress, it's a library of controls and themes for Angular2 applying Material Design and is an excellent source for learning to build your own control library.

Related

is it possible to use typescript and javscript together in a nativescript project

i would like to know if i can use javascript and typescript in one project and how.
i have an existing nativescript core js project, i want to use a plugin, the demo is written in TS, and its a webrtc plugin so i don't understand it enough to start messing with the code
i have tried running tns install typescript before but it messed up my project.
Basic considerations:
When you use TypeScript, you have to know it is not a runtime language, is a compiled language.
When you compile a TypeScript file, project or module, the TypeScript compiler (tsc) will generate the JavaScript files (usually CommonJS modules) according to the ECMAScript specification defined in the project (in TypeScript) config.ts file.
If you need to use a plugin in JavaScript but it is programmed in TypeScript, you have to compile it first, and then import the module/s in you JavaScript project.
Advanced considerations:
The ECMAScript specification version defined in the config.ts file, need to be compatible with your project JavaScript version.
There is no way to integrate TypeScript in a JavaScript project using the same execution context, even if you use JavaScript with the ES6 specification. Remember, JavaScript is an interpreted language, not compiled.
Conclusions:
Consider to migrate your code to TypeScript, compile the plugin and add it manually or search an alternative for that plugin in JavaScript.
PD: Check this related issue in the nativescript-webrtc GitHub repository

Vanilla JavaScript NPM web project starter

I'm looking for NPM toolset to help me to create baseline for Web projects with vanilla JS. So, as we set up Angular projects with angular-cli ng init command, React projects with create-react-app, is there any recommended NPM global tooling to set up all common toolchain (mainly Webpack, Babel and some development server with hot reloading/change detection) for non framework based projects?
Thank you for any suggestinos
I'd look at yeoman and available generators to pick one that suits your needs the most.
Here's a couple that might fit you:
webapp generator
babel boilerplate
grunt provides scaffolding. There are templates available, or it's fairly easy to create your own.

SystemJS - TypeScript loader use cases

I have a question regarding following TypeScript plugin for SystemJS :
https://github.com/frankwallis/plugin-typescript/
Here is its description
A plugin for SystemJS which enables you to System.import TypeScript files directly. The files are compiled in the browser and compilation errors written to the console.
I wonder what would be the use cases of such plugin.
Why would developers import directly ts files and compile them in the browser instead of compiling them during development and import js files ?
Won't it reduce performance and load time to do it in browser ?
Is it supposed to be used only in development environment ?
plugin-typescript author here. In-browser compilation is strictly a development tool, in production you would use systemjs-builder (in combination with plugin-typescript) to create a single file containing all of the transpiled javascript.
Since the plugin was originally developed, a number of new workflows have become available when using typescript & systemjs (typescript single-file transpilation, vscode, systemjs hot-reloading, typescript system.register output, to name a few...) - Which one is right for you will depend on the size of your application, the platform/server you are using, and your own personal preferences.
No one in their right mind would compile/transpile in the browser for production; it's the equivalent of sending a turtle to get your mail because you don't like walking.
This is strictly a development tool for helping TypeScript devs avoid having to constantly compile after every change, with the added benefit of providing features like hot reloading.

How to expose TypeScript modules in NodeJS?

I have a library that I'm building in TypeScript. I'd like to include this library in both TypeScript and JavaScript Node projects. What is the general strategy to do this? Should I compile and have two versions or is there some other strategy I should be using?
I'd like to include this library in both TypeScript and JavaScript Node projects. What is the general strategy to do this?
Compile with the following to get the js output:
--module commonjs --outDir ./dist
This should make your project consumable by JS projects. To make it consumable by TS projects you need to generate a declaration file. This can be done using https://github.com/SitePen/dts-generator See usage for details : https://github.com/SitePen/dts-generator#usage
Note: There is discussion on removing the dts-generator dependency : https://github.com/Microsoft/TypeScript/issues/2338
In most cases I have seen you have a /dist/ folder where the compiled JavaScript is located.
Usually there is also a minified version like yourfilename.min.js - the rest is either outside or in a /src/ folder, so outside you have only the license/readme.md, package.json left and maybe the file for Grunt/Gulp (it is considered polite to - if you use a taskrunner - include a Grunt/Gulp file for compiling the typescript and minify the .js file afterwards, as far as I got it)
If you want to preserve the TypeScript advantages when using it in TypeScript projects, then you obviously have to expose a TypeScript version of the code so the TypeScript compiler can see the TypeScript declarations for your interface.
But, if you want people to be able to use your library in plain Javascript projects (that don't compile TypeScript into JS), then you have to offer a version that has a plain Javascript interface and where the code has already been compiled into plain JS.
So, if you want both of those advantages, then you have to offer two separate versions. The plain JS version can obviously just be a compiled version of the TypeScript (compiled into plain JS).

how to create an environment agnostic javascript library

I'm creating a javascript library, and i want it to be environment agnostic (It will not use DOM, AJAX, or NodeJS api. It will be vanilla javascript). So, it's supposed to run in any javascript environment (browsers, npm, meteor smart packages, V8 C bindings...).
My currently approach is creating git repo with the library, with all the library inside a single global variable, without thinking about patterns like CommonJS or AMD.
Later, i'll create another git repo, using my library as a git submodule, and create what is needed to release it as a npm module. I'm concerned if it's a good approach, i didn't found anyone doing this way.
Pros: code will be vanilla javascript, without awareness of environment patterns. It will not bind itself to CommonJS. It will be repackable (copy and paste or git submodule) to any javascript environment. It will be as small as needed to be sent to browsers.
Cons: I'll have to maintain as many git as environments i want to support. At least a second git repo to deliver on npm.
Taking jQuery as example, it runs in both browser and nodejs, with just one git repo. There is some code to be aware of the "exports" variable to run on nodejs or other CommonJS compatible enviroment.
Pros: Just one git repo to mantain.
Cons: It will be binded to CommonJS pattern (to achieve npm compatibility)
My question is: Am i following a correct (or acceptable) approach? Or should i follow jquery's path, and try to create a single git repo?
Update 1:
Browserify and other require() libraries are not valid answers. My question is not how to use require() on the browser, instead, it's about the architecture pattern to achieve enviroment agnosticism.
Update 2:
Create a browser/nodejs module is not the question, it's known. The question is: can make a real enviroment agnostic library? This example is binded to CommonJS pattern, used in NodeJS.
If you are looking for design recommendation for your future library work then in my opinion you can think-future and just use usual Object Oriented Practices well proven in other languages, systems and libraries.
Mainly concentrate on the UML view of your design.
Forget the "one variable" requirement.
Use features proposed in the planned next version of JavaScript.
http://wiki.ecmascript.org/doku.php?id=strawman:maximally_minimal_classes
http://wiki.ecmascript.org/doku.php?id=harmony:modules_rationale
There is an experimental compiler available that allows you to write ES6-style code even today (see https://www.npmjs.org/package/es6-module-transpiler-rewrite).
Node.js has a --harmony command line switch that allows for the same (see What does `node --harmony` do?)
So in my opinion correct approach is to follow best practices and "think future"
"Use a build tool" is the answer for this question. With a build tool, you can develop with the best code pratices, without accopling your code to some enviroment standard of today (AMD, commonjs...) and still publish your code to these kind of enviroments.
For example, I'm using Grunt.js to run some tasks, like build, lint, test, etc.
It perform tedious operations (minification, compilation...) like Make, Maven, Gulp.js, and various others.
The build task can handle standards (like commonjs) for the compiled code. So, the library can be totally enviroment agnostic, and the build process handle enviroment adaptations.
Note that i'm not talking about compiling to binaries. It's compiling source to another source, like CoffeScript to JavaScript. In my case, it's compilation of JavaScript without enviroment standard to JavaScript with commonjs standard (to run as a Node.js module).
The final result is that i can compile my project to various standards without messing with my code.
Aditionally, with a build phase i can "think-future", like xmojmr answered and use the EcmaScript 6 features on my JavaScript code, using Grunt plugins like grunt-es6-transpiler or grunt-traceur to compile JavaScript code from ES 6 to 5 (so it can run on enviroments of today)
According to modular your library (if you need modules). Read this question Relation between CommonJS, AMD and RequireJS?
Take bootstrap for example, it uses npm to manage project dependencies and use bower to publish as static content for other web apps.
Take a look at browserify as reference, it's a little heavy because it provides the capability to bundle dependent npm modules as resource for browsers.

Categories