Globally-available mixin in VueJS - ecmascript-6

I'm trying to create a mixin that's globally available, but not automatically injected into every component. i.e. i do NOT want this: Vue.mixin({...});
I set up the project according to these instructions. This is my project structure. I also have assets/js/mixins.js file in there containing my mixins.
I would like to be able to do this in my individual .vue files (many of my components use myMixin but not all of them):
<script>
export default {
mixins:[myMixin],
data:{....}
}
</script>
<template>
<!-- some template code -->
</template>
So far the only way to do that is to add this line to the top of every component that needs it:
import {myMixin} from './assets/js/mixins.js"
but is there a way to do this once and have myMixin variable available globally? I've tried including it in main.js and in app.vue but I still get "myMixin is not defined" error if I try to use myMixin in any of the child components.
Or is there another way to register a mixin that doesn't require me typing the path to the mixins.js file in each component?

I would suggest setting your mixin up as a plugin. To do that, wrap it within an function call install and export the install function. Then, wherever your instantiate your app, you can simply do Vue.use(yourMixin):
Docs:
https://vuejs.org/guide/plugins.html
http://vuejs.org/api/#Vue-mixin
Example:
//- build your mixin
const mixin = {
// do something
}
//- export it as a plugin
export default {
install (Vue, options) {
Vue.mixin(mixin)
}
}
//- make it globally available
import myMixin from './myMixin'
Vue.use(myMixin)
Vue.use calls in the install fn(), so all subsequent Vues (or all if none have yet been created) have the mixin functionality
Careful of namespace clashes on globally available mixins (!)

A couple of ideas:
In main.js you can declare window.myMixin = {...}, which I believe will make it available in any component loaded after that.
edit: this is even better if you use this.myMixin, as this will refer to the global scope. That way you aren't depending on window existing, so it could be used in more environments
To not have to declare the full path in each file, you could create the mixin as a local NPM module as per Installing a local module using npm?. Then you could just import myMixin from 'myMixin'. This would be the more proper way to do it I think, that way you're still loading dependencies in each component, just with some shorthand.

Here is the correct way to register a mixin globally in app.js
Vue.mixin(myMixin);

Related

How do I import the Three.js Line library as an ES6 module?

I do my development using modern JS (ES6) which means modules.
Although Three.js is available as an ES6 module. The line library - LineSegmentsGeometry, LineGeometry, LineSegments2, etc. - is not.
What are my options here?
You have a couple options.
First and foremost, edit the code.
You're welcome to modify the code, and so you could manually turn it into an ES6 module. You would want to remove any references of THREE, and export anything that was normally attached to that object. You'll also need to import any required core THREE.js components, like Mesh, Vector3, etc.
The way I prefer to do this is to copy the file I'm updating locally, and change references to it. For example:
// local_three_modules/LineSegments2.js
import { Mesh, Vector3, etc. } from "three"
let LineSegments2 = function ( geometry, material ) {
// ...
}
export default LineSegments2
// app.js
import { Mesh, Vector3, etc. } from "three"
import LineSegments2 from "./local_three_overrides/LineSegments2.js"
// and so on...
Your other option is to use a bundler with an export loader.
Webpack (and other bundlers, I'm just more familiar with Webpack) provides a exports-loader which can be used against specific files that don't export anything. For example, you can tell the exports-loader to export THREE from LineSegments2.js. To get webpack involved in this process, you need to tell it to use the loader on the file. You can do this through the webpack configuration, or inline in the code like this:
import THREE from "exports-loader?THREE!./node_modules/three/examples/js/lines/LineSegments2.js"

How do I use Yeoman's git.name(); mixin?

I'm running yeoman with gulp and I want to print a user's github name using this mixin: http://yeoman.io/generator/actions_user.html#.git.name
Simply adding var username = git.name(); doesn't work
How can I use this mixin and other mixins in yeoman? Do I need to require or include anything in index.js file other than yeoman itself?
No need to import anything. Just prefix the call with this.user. This applies to your example as such:
var username = this.user.git.name());
This makes it somewhat inconsistent with the other mixins outside of this.user, which can be accessed directly via this, eg. this.installDependencies().

How to register coffeescript transpiler in ES6 way?

Previously I've been using following in my JS entry points:
require('coffeescript/register');
module.exports = require('./entry.coffee');
What is the corresponding ES6 syntax of this?
Following does not seem to register anyhing.
import 'coffeescript/register';
export * from 'entry.coffee';
Error is:
Cannot find module 'entry.coffee'
Tested on Coffeescript 2.0 beta2.
Update:
Changing path to relative:
import 'coffeescript/register';
export * from './entry.coffee';
finds the entry.coffee, but treats it as JS. Hence, Coffeescript is not handled by transpiler.
You don't need to use coffeescript/register if you're transpiling the CoffeeScript as part of your bundling process (which you need to, if you're using Rollup) — that's just a way to enable Node to run CoffeeScript files without having to first convert them.
Instead, try adding rollup-plugin-coffee-script to your rollup.config.js file.

Using ES6 `import` with CSS/HTML files in Meteor project: bug or feature?

I am currently learning Meteor and I found out something that intrigued me.
I can load HTML and CSS assets from a JS file using the import statement.
import '../imports/hello/myapp.html';
import '../imports/hello/myapp.css';
import * as myApp from '../imports/hello/myapp.js';
This was a surprise to me so I ran to google but could not find this behavior documented in the specification for ES6 import or in Meteor's Docs.
So my questions are:
Can I rely on this behavior to build my apps?
Will my app will break when Meteor gets around to fix it -- if it's a bug --?
Notes
I am using Meteor v1.3, not sure if this works also with previous versions.
You can download the app to see this behavior from Github
After going through the implementation of the built files for my app
I found out why this works.
HTML
Files are read from the file system and their contents added to the global Template object, e.g.,
== myapp.html ==
<body>
<h1>Welcome to Meteor!</h1>
{{> hello}}
</body>
results in the following JS code:
Template.body.addContent((function () {
var view = this;
return [
HTML.Raw("<h1>Welcome to Meteor!</h1>\n\n "),
Spacebars.include(view.lookupTemplate("hello"))
];
}));
Which is wrapped in a function with the name of the file as it's key:
"myapp.html": function (require, exports, module) {
Template.body.addContent((function () {
var view = this;
return [
HTML.Raw("<h1>Welcome to Meteor!</h1>\n\n "),
Spacebars.include(view.lookupTemplate("hello"))];
}));
Meteor.startup(Template.body.renderToDocument);
Template.__checkName("hello");
Template["hello"] = new Template("Template.hello", (
function () {
var view = this;
return [
HTML.Raw("<button>Click Me</button>\n "),
HTML.P("You've pressed the button ",
Blaze.View("lookup:counter",
function () {
return Spacebars.mustache(view.lookup("counter"));
}), " times.")
];
}));
},
So all of our HTML is now pure JS code which will be included by using require like any other module.
CSS
The files are also read from the file system and their contents are embedded also in JS functions, e.g.
== myapp.css ==
/* CSS declarations go here */
body {
background-color: lightblue;
}
Gets transformed into:
"myapp.css": ["meteor/modules", function (require, exports, module) {
module.exports = require("meteor/modules").addStyles("/* CSS declarations go here */\n\nbody {\n background-color: lightblue;\n}\n");
}]
So all of our CSS is also now a JS module that's again imported later on by using require.
Conclusion
All files are in one way or another converted to JS modules that follow similar rules for inclusion as AMD/CommonJS modules.
They will be included/bundled if another module refers to them. And since all of them are transformed to JS code
there's no magic behind the deceitful syntax:
import '../imports/hello/myapp.html';
import '../imports/hello/myapp.css';
They both are transpiled to their equivalent forms with require once the assets have been transformed to JS modules.
Whereas the approach of placing static assets in the imports directory is not mentioned in the official documentation,
this way of importing static assets works.
This seems to be at the core of how Meteor works so I'd bet this functionality is going to be there for a long while.
I don't know if to call this a feature maybe a more appropriate description is unexpected consequence but that would
only be true from the user's perspective, I assume the people who wrote the code understood this would happen and perhaps even
designed it purposely this way.
One of the features in Meteor 1.3 is lazy-loading where you place your files in the /imports folder and will not be evaluated eagerly.
Quote from Meteor Guide:
To fully use the module system and ensure that our code only runs when
we ask it to, we recommend that all of your application code should be
placed inside the imports/ directory. This means that the Meteor build
system will only bundle and include that file if it is referenced from
another file using an import.
So you can lazy load your css files by importing them from the /imports folder. I would say it's a feature.
ES6 export and import functionally are available in Meteor 1.3. You should not be importing HTML and CSS files if you are using Blaze, the current default templating enginge. The import/export functionality is there, but you may be using the wrong approach for building your views.

how to force compiler compile all classes in my project?

im using Adobe® Flash® Builder™ 4.6,the problem also exist in previous versions.
for some reason ,i am using
cls = applicationDomain.getDefinition(name) as Class;
to get the object's constructor and then create the instance of my modules class.thus make compile ignore my module classes ,because they are not related from my main class.how to force else classes also compiled into my swf or swc file? i didn't find where i can adjust my compile option.
by now i use this way to solve my problem,at the very beginning of the program entry.
if(1+1==3){
//never be run but do make classes merge into swf files.
new MyModule();
}
i have hundreds of modules like this one,i do hope i can find a way to solve this problem permanently
You can try with this
package
{
public class IncludeClasses
{
import com.abc.db.Database;Database;
import com.abc.logs.RemoteLogTarget; RemoteLogTarget;
import com.abc.logs.LocalLogTarget; LocalLogTarget;
import com.abc.exception.GlobalExceptionHandler; GlobalExceptionHandler;
import com.abc.utils.NetConnectionMonitor;NetConnectionMonitor;
}
}
You need to use the class to get it to compile in the swf.
Not the best method but
private var someVar:someClass;
Using the "new" keyword will cause the run-time to allocate memory for the object so you don't want to use that.
This whole loading modules and compiling classes has a code smell to it.
You would be better off having your classes in the modules implement an interface.
You need at least one strict reference to your class to appear within the project. I use a static variable of type Array to stuff all of the classes I need, and never really reference that array, if I can.
private static var dummy:Array=[OneClass, AnotherClass, Class01, Etc];
You can also do this by setting your compiler flag.
About the application compiler options
See:
include-libraries library [...]
Include only classes that are inheritance dependencies of classes that
are included with the include-classes compiler option.
The default value is false.
This is an advanced option. You might use this compiler option if you
are creating a custom RSL and want to externalize as many classes as
possible. For example:
compc -include-classes mx.collections.ListCollectionView
-include-inheritance-dependencies-only=true
-source-path . -output lcv2 -directory