My folder structure is this:
./package.json
src/Notification.js
test/notification.js
File Notification.js
export defaultĀ {
template: '<div>{{message}}</div>',
data() {
return {
message: 'Hello world'
};
}
};
File notification.js
import Vue from 'vue';
import test from 'ava';
import Notification from '../src/Notification';
test('that it renders a notification', t => {
new Vue(Notification).$mount();
});
Error when i run: node_modules/.bin/ava
[Vue warn]: You are using the runtime-only build of Vue where the
template compiler is not available. Either pre-compile the templates
into render functions, or use the compiler-incluided build. (found in
<Root>)
1failed
that it renders a notification
test finished without running any assertions
If someone can say me what's wrong and explain the code, i will really appreciate it.
Your test did not use any assertions. You probably want to assert something on the new Vue(Notification).$mount() return value. If you're just making sure it doesn't throw an exception you could do t.notThrows(() => new Vue(Notification).$mount()).
Vue ships with several versions, some with the template compiler and some without. The way you are importing Vue now, the template compiler is not included, so Vue cannot compile
template: '<div>{{message}}</div>',
Try instead importing a version of Vue with the compiler.
import Vue from "vue/dist/vue"
Related
Following is the entry point to my library, it generates a component with a dynamic tag:
// muvement.js
import { defineComponent, ref, onMounted, h } from 'vue';
const createMuvement = (tag) => {
return defineComponent({
name: `m-${tag}`,
setup(props, context) {
const root = ref(null);
onMounted(() => {
console.log(root.value);
});
return () => h(tag, { ...context.attrs, ref: root }, context.slots);
}
});
};
const muvement = (...tags) => {
const components = {};
tags.map((tag) => (components[`m-${tag}`] = createMuvement(tag)));
return components;
};
export { muvement };
It's expected to be consumed like so:
// Home.vue
<template>
<div>
<m-div>div</m-div>
<m-button>button</m-button>
</div>
</template>
<script>
import { muvement } from "muvement";
export default {
name: "Home",
components: {
...muvement("div", "button")
}
};
</script>
This works as expected when the library code is contained within the Vue app folder (assuming we are now importing from "#/components/muvement.js" instead of "movement").
That is:
-muvement-test-project (scaffolded with vue-cli)
- src
- views
- Home.vue
- components
- muvement.js
I've also published an alpha release that works fine when importing "muvement" after installing it directly from the npm registry (that is, npm install muvement instead of npm link muvement).
The Problem
During development, I want an app to test the library with that is separate from the library's directory.
I've used npm link to link the library to the test app (as I have done with many other projects in the past).
From /path/to/library
$ npm link
From /path/to/test/app
$ npm link muvement
So far so good. The module is available as a symlink in the test app's node_modules folder. So I import { muvement } from "muvement", run npm run serve, and... BOOM.
Everything explodes (see errors below). It's also probably worth noting that trying to import from the full path (i.e. C:/dev/npm/muvment/dist/es/index.js) results in the same issues as npm link does, so I don't think it has anything to do with the symlink directly.
This is what appears in the console:
For pretty much the entire day I have been trying to solve this one issue. I've seen several seemingly similar questions that were solved by settings Webpack's resolve.symlinks to false but that has no effect on my problem. I've read all through the docs and even Vue's source code (here is the offending line for those who are curious).
Since the warning suggests that the error is commonly attributed to async setup I thought maybe webpack was doing something weird that would make my code async. This doesn't seem to be the case as the call stack of both the working attempt and failed attempt are identical.
What's not identical is the scope.
Here is the scope for the example that is working:
And here is the failing one:
(Notice that the target parameter is null during the call to injectHook, which is obviously what prompts Vue to show a warning).
My question is, why does the location of the imported module make such a difference during the execution of the said module?
The library code and build setup are available here:
https://github.com/justintaddei/muvement
The test app is available here:
https://github.com/justintaddei/muvement/tree/example
If I've left out something important, please let me know in the comments. It's been a long day so I'm sure I've probably missed something.
Thank you.
The problem is your app is using two different vue dependencies under the hood - vue requires the same dependency to be used to keep track on reactivity, lifecycle, etc.
When you link a library npm/yarn will use that linked folder node_modules, but your app is using it's dependencies from it's node_modules.
When your app imports vue it will go app/node_modules/vue but when you import from your linked dependency it will be going to linked_dep/node_modules/vue.
app
node_modules
vue
linked library
node_modules
vue
One easy way to debug this issue is to change both vue dependency files with a console.log and check if the console is logging both.
I have this Vue plugin that is not working:
import _Vue from "vue";
import particles from "./Particles.vue";
const VueParticles = (Vue: typeof _Vue, options: unknown) => {
_Vue.component('Particles', particles);
};
export { particles as ParticlesComponent };
export default VueParticles;
It builds, but if I try to use it, it doesn't load the component and the app returns me this error:
[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
---> at src/App.vue
And I load the plugin like this:
import Particles from "particles.vue";
Vue.use(Particles);
But if I load the component using the Vue.component syntax, it's working, like this:
import { ParticlesComponent } from "particles.vue";
Vue.component("Particles", ParticlesComponent);
This is the template I'm using:
<Particles id="tsparticles" :options="options" :particlesInit="particlesInit" :particlesLoaded="particlesLoaded"/>
You can try to replicate the issue following these steps:
Clone tsParticles dev branch with: git clone https://github.com/matteobruni/tsparticles.git --branch dev
Run yarn && npx lerna bootstrap && npx lerna run build
Go to demo/vue folder
Run yarn serve and open http://localhost:8080, everything should work (an animated background should start animating)
Edit src/App.vue commenting the working Vue.component and restoring the Vue.use
Rerun yarn serve and open http://localhost:8080, the background this time is not appearing
I just switched from yarn workspaces to standard yarn for big issues with the node dependencies in the whole project
I don't understand why it broke like this.
I also tried an external Vue.js app instead of the demo one inside the project but nothing changed.
The component is using vue-property-decorator but I tried switching to the Vue.extend syntax and nothing changed so I reverted to the previous class code.
The plugin file should be exporting an object with an install function, but your plugin just exports the function itself. Also, the install function's argument should be used in the body (i.e., Vue is the argument name, so the body should contain Vue.component()).
The fix should look like this:
const VueParticles = {
install(Vue: typeof _Vue, options: unknown) {
Vue.component('Particles', particles);
}
};
export default VueParticles;
I am trying to manually include the #material/drawer npm package into my Ember app. I tried following this guide but I'm running into some weird errors in my Chrome dev console:
Uncaught SyntaxError: Unexpected token *
Uncaught ReferenceError: define is not defined
The first is from the imported node_modules/#material/drawer/index.js file and the second is from my generated shim.
My component code:
import Component from '#ember/component';
import { MDCTemporaryDrawer, MDCTemporaryDrawerFoundation, util } from '#material/drawer';
export default Component.extend({
init() {
this._super(...arguments);
const drawer = new MDCTemporaryDrawer(document.querySelector('.mdc-drawer--temporary'));
document.querySelector('.menu').addEventListener('click', () => drawer.open = true);
}
});
In my ember-cli-build.js:
app.import('node_modules/#material/drawer/index.js');
app.import('vendor/shims/#material/drawer.js');
My generated shim:
(function() {
function vendorModule() {
'use strict';
return {
'default': self['#material/drawer'],
__esModule: true,
};
}
define('#material/drawer', [], vendorModule);
})();
What exactly am I doing wrong? It almost seems as though raw ES6 code got imported rather than compiled into my JS build output.
I also read this SO post but there are too many answers and I'm not sure which to do. It seems this specific answer is what I'm trying to do but not verbatim enough.
Creating a shim only ensures that ember-cli gets an AMD module, which you then can import in your app files.
If the npm package needs a build or transpiling step beforhand, this won't work.
You need a way to get the package build within the ember-cli build pipeline.
Luckily there are addons which can take care of this for you: ember-auto-import and ember-cli-cjs-transform.
You may have also heard of ember-browserify, which does the same thing, but it's deprectaed in favor of ember-auto-import.
I'd suggest you try ember-auto-import:
ember install ember-auto-import
You then should be able to import as you tried:
import { MDCTemporaryDrawer, MDCTemporaryDrawerFoundation, util } from '#material/drawer';
No shim or app.import needed, as ember-auto-import will take care of this for you.
Using Vue (^2.0.0-rc.6) + Browserify, entry point is index.js:
import Vue from 'vue'
import App from './containers/App.vue'
new Vue({ // eslint-disable-line no-new
el: '#root',
render: (h) => h(App)
})
App.vue:
<template>
<div id="root">
<hello></hello>
</div>
</template>
<script>
import Hello from '../components/Hello.vue'
export default {
components: {
Hello
}
}
</script>
<style>
body {
font-family: Helvetica, sans-serif;
}
</style>
Hello.vue:
<template>
<div class="hello">
<h1>\{{ msg }}</h1>
</div>
</template>
<script>
export default {
data () {
return {
msg: 'Hello Vue!'
}
}
}
</script>
Blank white screen, did I miss something?
EDIT:
The entry html is just <div id="root"></div>, no errors on console logs, and I'm pretty sure Hello.vue is loaded since console.log('test') that file appears on console.
EDIT 2:
Found the error:
[Vue warn]: You are using the runtime-only build of Vue where the
template option is not available. Either pre-compile the templates
into render functions, or use the compiler-included build. (found in
anonymous component - use the "name" option for better debugging
messages.)
Does this mean I have to use webpack solution? Cannot use standard HTML?
SOLUTION:
Import Vue from 'vue/dist/vue.js'
Just to make life easier for folks looking for the answer:
import Vue from 'vue/dist/vue.js'
import App from './App.vue'
new Vue({
el: '#app',
render: h => h(App)
})
From the author -- 2.0 standalone build means (compiler + runtime). The default export of the NPM package will be runtime only, because if installing from NPM, you will likely pre-compile the templates with a build tool.
If you are using a build tool like browserify or Webpack, you can most probably use single file components to avoid such errors (in single file components the templates are automatically compiled to render functions by vueify). You definitely should try to avoid templates anywhere else. Check the forum and documentation for answers about how to avoid them.
But I know from my own experience that it is not always easy to find the templates in your project, that are causing the error message. If you are having the same problem, as a temporary workaround, the following should help:
You should not import 'vue/dist/vue.js' (check the documentation: https://github.com/vuejs/vue/wiki/Vue-2.0-RC-Starter-Resources#standalone-vs-runtime-builds why not)
Instead you should handle that in the build tool you are using.
In my case, I'm using browserify where you can use aliasify for creating the alias. Add the following to your package.json file:
{
// ...
"browser": {
"vue": "vue/dist/vue.common.js"
}
}
for Webpack users it seems you have to add the following to your config:
resolve: {
alias: {vue: 'vue/dist/vue.js'}
},
More information can be found in the documentation: https://v2.vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only
For Vue 3.4.0 You can add a new file at the root directory of the project named
vue.config.js and add the following into it.
module.exports = {
runtimeCompiler: true
}
Next time when you start the app you can see
Compiled successfully in 204ms
20:46:46
App running at:
With Brunch I resolved this by adding this rule in brunch-config.js:
npm: {
aliases: {
vue: "vue/dist/vue.js"
}
}
see http://brunch.io/docs/config#npm
It was to build a Vue component with an inner <template>:
<template>
<div> hello </div>
</template>
<script>
export default {
name: 'Hello',
props: {
title: String,
},
}
</script>
I am trying to make a workflow, where I can write React modules using TypeScript and automatic compiling to JavaScript via Gulp.js. I am using TypeScript 1.6.2, gulp-react and gulp-typescript.
My .tsx file looks like this now:
/// <reference path="../../../../typings/react/react.d.ts" />
import React = __React;
interface HelloWorldProps {
name: string;
}
var HelloMessage = React.createClass<HelloWorldProps, any>({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
React.render(<HelloMessage name="helloooo" />, document.getElementById('test'));
My problem is this line: import React = __React;
When I leave it out, I get the error
error TS2304: Cannot find name 'React'.`
when compiling .tsx to .js (but it still compiles to JSX, and I can use the output). When I put it in, I can compile without errors, but when I try to use the file inside the browser, I get an Uncaught ReferenceError: __React is not defined, of course.
This is how my gulptask looks like:
gulp.task('gui-tsx', function () {
var tsResult = gulp.src(config.guiSrcPath + 'tsx/app.tsx')
.pipe(ts({
jsx: 'react'
}));
return tsResult.js.pipe(gulp.dest(config.guiSrcPath + 'jsx'));
});
Is there a workaround for this? Or am I missing something here?
Okay, I found a solution. First install the React global definition via tsd:
tsd install react-global
This will create a file, react-global.d.ts, in your typings directory, which you have to reference in you root component file (the path is relative, so adjust it to your needs):
/// <reference path="../../../../typings/react/react-global.d.ts" />
After that it compiles without errors.
where I can write react modules using typescript and automatic compiling to js via gulp
Highly recommend you don't use global modules. Instead compile with --module commonjs and embrace the react / webpack / nodejs ecosystem.
You can checkout an example application here : https://github.com/basarat/tsb/tree/master