Aurelia: How to use a View/Viewmodel from an npm package? - javascript

We are using Aurelia for our application's frontend. As we will have several different projects based on it, I would like to be able to add all of our custom code to some npm packages that could be added by the developers.
This would allow us to create a new empty project, add the dependencies to our reusable code without including it in the project's code base (so it can be updated separately if needed).
For instance, I would like a tools package and a service package. This is of course quite easy.
But I can't figure out how to use a 'ui' package that would contain all our custom reusable components. Is that even possible? How would I require a component in an html template?
If this can't be done, does anyone have an idea of how to cleanly separate the reusable code from the application specific code?
thanks a lot!

of course you can, that's what a lot of the plugins available for aurelia doing.
One way is to register your components as global resources (in your package or plugin) and import them in your client app, CLI example:
// from your plugin
aureliaConfig.globalResources([
'./jqm-loader',
'./jqm-page',
'./jqm-footer',
'./jqm-header'
]);
then import them in your app:
// aurelia.json
{
"name": "my-reusable-widgets",
"path": "../node_modules/my-reusable-widgets",
"main": "index",
"resources": [
"**/*.{css,html}" //to load them all or you can add individual files
]
}
then use your widgets:
<jqm-loader></jqm-loader>
...
if you don't want to use globalResources you can also use require:
<require from="my-reusable-widgets/jqm-header"></require>
<jqm-header></jqm-header>

Related

Unable to understand the difference between different monaco editor packages integration

I have a react application, and I want to embed Monaco Editor into my application mainly for SQL validation and AutoComplete scenarios. I use neutrinorc.js to configure plugins or direct install using npm install plugin-name in the application.
My webpack.config.js looks like,
// Whilst the configuration object can be modified here, the recommended way of making
// changes is via the presets' options or Neutrino's API in `.neutrinorc.js` instead.
// Neutrino's inspect feature can be used to view/export the generated configuration.
const neutrino = require('neutrino');
module.exports = neutrino().webpack();
I noticed that there is,
https://github.com/react-monaco-editor/react-monaco-editor
https://github.com/jaywcjlove/react-monacoeditor
And Microsoft ones,
https://github.com/microsoft/monaco-editor-webpack-plugin
https://github.com/Microsoft/monaco-editor
I don't understand that if I want to embed a Monaco Editor into my React application which of the above packages do I need and do I need to configure them in neutrinorc.js?
It would be great if someone can explain this in detail.
I don't know neutrinorc.js, but I can explain the other aspects. Integrating Monaco in a React app requires 2 things:
A React wrapper for the Monaco editor. You can either write one yourself or use the react-monaco-editor node module.
You have to configure webpack to load the required files. This is where monaco-editor-webpack-plugin comes in.
Especially the second point is a bit tricky, depending on your app. If you created that using CRA (create-react-app) you will not have access to the webpack config file, unless you "eject" the app. This is usually not desirable, hence add another node module to the mix, called react-app-rewired. This module allows you to add another webpack config file (config-overrides.js) to the root of your project and add configuration data there. Something like:
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const webpack = require("webpack");
module.exports = function override(config, env) {
config.plugins.push(new MonacoWebpackPlugin({
languages: ["typescript", "javascript", "sql", "mysql", "python", "json", "markdown", "ini", "xml"]
})
return config;
}
With that webpack plugin you can decide which language you want to support in Monaco and distribute only those files required by them (especially TS + JS require quite large files to be there).

Angular CLI 6: How to consume a library sub-project in the main application?

I've got an Angular 6 project that's made of up a main application, and a separate sub-project that is a library. I'm trying to consume this library from the main application, and I can't seem to get it working.
In the tsconfig.json, I have the following paths configuration:
"paths": {
"#my-company/my-package/*": "dist/my-package/*"
}
And then in the main app, I import the library like so:
import { ButtonModule } from '#my-company/my-package/button';
However, when I build the main application, I get tons of errors about not being able to find modules. For the above import statement, I'll get this error:
Module not found: Error: Can't resolve '/Users/jattardi/code/myproject/dist/my-package/button'
However, if I check the dist/my-package directory, there certainly is a button directory containing the type definitions.
The reason my imports have subpaths, e.g. #my-company/my-package/button instead of just #my-company/my-package is to make it tree-shakeable. Not sure this is possible. Since this is an Angular 6/ng-packagr generated build, do I lose this ability?
I was hit with the same error when trying to consume in the main application. My answer will not solve that case as I am trying to get my lazy loaded module, I moved into the new Angular6 library, to work.
I was able to publish my library project to npm and consume it in the main application as an npm dependency. For eg: #santony/ngx-material. May be as a workaround you could do that until this is resolved.
For those who are still facing this problem, there's a "how to" at ng-packagr's documentation:
https://github.com/ng-packagr/ng-packagr/blob/master/docs/secondary-entrypoints.md
Basically,
All you have to do is create a package.json file and put it where you want a secondary entry point to be created.
The contents of my_package/testing/package.json can be as simple as:
{
"ngPackage": {}
}
And also, in dev application, I've added the path reference to the secondary endpoint, so it worked:
"#my-company/my-library/another": [
"dist/my-library/another"
]

Attempting to load a JavaScript sdk into an Angular2 application. Can't find all dependencies

I'm attempting to make use of this library: https://github.com/MagicTheGathering/mtg-sdk-javascript in an Angular2 application.
Unfortunately, I've been going in circles trying to load it into my application.
Firstly, on the TypeScript side if I import it using:
import { } from 'mtgsdk';
there are no types to load into the {}.
If I attempt to load it using something similar to:
import * as mtg from 'mtgsdk'
I'm unable to because it says that it's unable to find a module named mtgsdk.
I've installed the module using
npm install --save mtgsdk
Also, npm installs work fine for other modules.
The application compiles fine if I load it in using require via something similar to this:
var mtg = require('mtgsdk');
Taking that approach, I'm able to compile and launch but in the browser I get a number of errors about modules that it can't find. I figure they are prerequisites for the sdk that didn't get loaded so I start bringing them in via package.json.
For every one that I bring in, I then have to go to systemjs.config.js and add an entry pointing to the module's entry point and often have to specify a default extension using blocks like this:
pointer
'mtgsdk': 'npm:mtgsdk/lib/index.js',
'request-promise': 'npm:request-promise/lib/rp.js',
'ramda': 'npm:ramda/dist/ramda.js',
'emitter20': 'npm:emitter20/index.js',
'bluebird': 'npm:bluebird/js/browser/bluebird.js',
'request': 'npm:request/index.js'
default extension
'request-promise':
{
defaultExtension: 'js'
}
I'm not sure if that's the right approach though because the more dependencies I add, the more that I end up requiring. At one point I had literally gotten up to 50 extra dependencies added because every time I launched, the browser console would find more that were needed.
Is there any easier way to load all of these in?
Also, some of them (such as tough-cookie and request-promise-core) were very problematic to load and I couldn't get the browser console to stop complaining about them. Finally, some of them seemed very basic such as url, http, https. Those seem like they should already be present.
Using systemjs was utilized in the previous versions of Angular 2, However Angular 2 has evolved to Angular 4, with super new features like Angular CLI.
I recommend your use Angular CLI, with #angular/cli.
Importing Node modules
Since mtgsdk is a node-module, you can easily import it using
import * as mtg from 'mtgsdk'
However for your program to compile, you must install a type definition for it. or declare one for it in /typings.json or your app might not build.
Importing Client Scripts
For client scripts like firebase.js you won't need to add client scripts as entries in systemjs.config.js again.
Using #angular/cli, you would easily add them in the scripts[] array in your angular-cli.json for automatic compilation.
Then access them like this
declare const firebase: any;
Here is a quickstart tutorial to set up Angular with #angular/cli.

Changing Vue.js from standalone to runtime-only build later in a project?

Went with the runtime-only build version of Vue.js for a new project. I saw in the docs that to switch to the standalone one needs to add an alias to webpack, like so:
resolve: {
alias: {
'vue$': 'vue/dist/vue.js'
}
}
At the moment, I don't need the compiler in my app. However, it's possible that at some point I will need to switch to the standalone build.
My question is:
Will it be a painless switch between runtime-only and standalone later or will it require heavy refactoring?
If it does, I might as well start with standalone and avoid refactoring later on.
standalone supports template option in components. For example, you can do this:
Vue.component('my-component', {
template: '<div>A custom component!</div>'
})
standalone also allows you to load vue.js from a CDN, like you would do with jQuery or any other javascript library.
runtime-only does not allow you to use template in component definition. So you need to create my-component.vue file and define template inside as detailed in Single File Components guide: http://vuejs.org/guide/single-file-components.html
Also you need to use vue-cli for development, if you are using runtime-only.
To switch from standalone to runtime-only, you will have to rewrite all the components into my-component.vue files, and start using vue-cli
To switch from runtime-only to standalone, there are no changes required.
Other than that, it is painless to switch between runtime-only and standalone.
My preference: runtime-only only mode, as it produces much smaller builds and theoretically performs better, as templates are pre-compiled. Also the sections in vue file are well organized and easy to read. Separate vue files for components also forces you to structure your app better.

Why are there specific component.io libraries for jquery, jquery-ui, etc.

I've been looking into using component.io in a current project, as it seems much simpler than require.js and browserify, and I like a few things they've done.
Seeing as component.io doesn't require any component style wrappers, why does component.io have their own versions of jquery?
https://github.com/components/jqueryui
These seems to go counter to what they are proposing, as all component.io needs to know is the github username and project name in order to include the files.
If the only thing needed is the
"scripts": [
"ui/jquery-ui.js"
],
"main": "ui/jquery-ui.js",
tags in a component.js file, why not just have a component.js file which points to the main jquery-ui file?
as all component.io needs to know is the github username and project name in order to include the files.
No, that's not true
First of all - I think this should be clear before talking about component to avoid misunderstandings - component.io is only the website with a list of components using the package manager and build tool component developed by TJ Holowaychuk
'component' is ambiguous
Furthermore ComponentJS (http://componentjs.com) has nothing to do with it.
And also the component.json file in the context of bower has nothing to do with TJ's component. Bower renamed their component.json to bower.json and deprecated the old name
Nevertheless: some of the keys in bower's JSON are compatible to the JSON of TJ's component but that doesn't mean that a TJ component is build properly with a bower's component.json file.
To explain: No, that's not true you can read this form the componentjs/spec repository:
Components MUST provide a "component.json" file to describe the component's functionality and contents. Component developers MUST explicitly state the relevant file(s) via scripts, styles and others. [...|
To your question:
why not just have a component.js file which points to the main jquery-ui file
Usually someone can create a component.json file for an existing libarary like jQuery and send a pull request.
But the pull request might not be merged, because:
there is already a component.json for bower
the repository / build process don't contain/generate the needed files
project isn't maintained anymore
To be sure what's the reason in your case you can just ask at https://github.com/components/jqueryui/issues and/or
https://forum.jquery.com/developing-jquery-ui

Categories

Resources