vuejs-templates / webpack

A full-featured Webpack + vue-loader setup with hot reload, linting, testing & css extraction.
MIT License
9.7k stars 4.39k forks source link

Trying to use this with Vue 2. #215

Closed dan-gamble closed 8 years ago

dan-gamble commented 8 years ago

So i bumped Vue to beta 7 and vue-loader to 9.3.2 but i keep getting this warning and nothing is rendering

[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.

My small example is:

const App = {
  name: 'Test',
  render: h => {
    return (
      <div id="app">
        <h1>Basic</h1>
        <ul>
          <li><router-link to="/">/</router-link></li>
          <li><router-link to="/foo">/foo</router-link></li>
          <li><router-link to="/bar">/bar</router-link></li>
        </ul>
        <router-view />
      </div>
    )
  }
}
const Home = { template: '<div>home</div>' }
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

const router = new VueRouter({
  mode: 'history',
  base: __dirname,
  routes: [
    { path: '/', component: Home },
    { path: '/foo', component: Foo },
    { path: '/bar', component: Bar }
  ]
})

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

I've also tried:

const App = {
  template: `
    <div id="app">
      <h1>Basic</h1>
      <ul>
        <li><router-link to="/">/</router-link></li>
        <li><router-link to="/foo">/foo</router-link></li>
        <li><router-link to="/bar">/bar</router-link></li>
      </ul>
      <router-view class="view"></router-view>
    </div>`
}
const Home = { template: '<div>home</div>' }
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

const router = new VueRouter({
  mode: 'history',
  base: __dirname,
  routes: [
    { path: '/', component: Home },
    { path: '/foo', component: Foo },
    { path: '/bar', component: Bar }
  ]
})

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

To no avail, it's doing my head in, i'm sure it's a simple fix :(

yyx990803 commented 8 years ago

As the message suggests... read more here about the runtime only build.

To solve it you need to either add the following to your Webpack config:

resolve: {
  alias: {
    vue: 'vue/dist/vue.js'
  }
}

Or, make sure that all your components are defined in *.vue files, because they are pre-compiled.

dan-gamble commented 8 years ago

Awesome thanks Evan, i think it was a combination of my files actually having errors in them as i was trying to get them in a minimal state i forgot i didn't have store as well. 👍

ghost commented 7 years ago

This is a trap. I got in this trouble. so may you please improve the document ? add

Make sure that all your components are defined in *.vue files, because they are pre-compiled.
ghost commented 7 years ago

http://vuejs.org/guide/components.html#Local-Registration The local registration not working if we do not change webpack configure. and i do not know where to change the webpack configure. would you please past a complete webpack configure file for me ? @yyx990803

tylerbrgr commented 7 years ago

@netroby It's in the module.exports section:

module.exports = {
  entry: {
    app: './src/main.js'
  },
  output: {
    path: config.build.assetsRoot,
    publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath,
    filename: '[name].js'
  },
  resolve: {
    extensions: ['', '.js', '.vue'],
    fallback: [path.join(__dirname, '../node_modules')],
    alias: {
      'vue': 'vue/dist/vue.common.js',
      'src': path.resolve(__dirname, '../src'),
      'assets': path.resolve(__dirname, '../src/assets'),
      'components': path.resolve(__dirname, '../src/components')
    }
  },

remove 'common' and you're good

asvae commented 7 years ago

It appears for me that many-a-folks, having no idea, as to how to define a root component for runtime-only build, decide to use standalone. Which is not needed... As everything is compiled anyway.

So have a solution. Runtime-only and easy-peasy.

import Vue from 'vue'
import vmApp from './app.vue'

new Vue(vmApp).$mount('#app')

@yyx990803 Probably worth mentioning a thing in docs? I'm somewhat active in chat and have seen a bunch of people using standalone "just because".

tsankuanglee commented 7 years ago

@asvae could you provide an example of what's inside ./app.vue?

ghost commented 7 years ago

I thought there should be a lint tools. like vue-lint or some thing.

just check the grammar of app.vue and all other vue files

asvae commented 7 years ago

@tsankuanglee, sure. It's just a single file component. Or do you want to see the router config and stuff like that?

cbess commented 7 years ago

@tsankuanglee Here is a snippet.

// app.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './components/App.vue';
import Home from './components/Home.vue';

Vue.use(VueRouter);

const router = new VueRouter({
    routes: [{
        path: '/',
        name: 'home',
        component: Home
    },
// .. others
});

const app = new Vue({
    router,
    render: createEle => createEle(App)
}).$mount('#app-container');
// App.vue
<template>
    <div id="app">
        <p>
            <router-link to="/foo">Foo</router-link>
            <router-link to="/foo2">Foo 2</router-link>
        </p>
        <router-view></router-view>
    </div>
</template>

<script>
export default {
    // empty
}
</script>
<!-- index.html -->
<div id="app-container"></div>

The browserify example helped me.

tsankuanglee commented 7 years ago

Thank you, @asvae and @cbess . That's what I use, but I've always put it under component so I was a bit unsure about this syntax: Vue(vmApp). This is cleaner. Thanks!

up9cloud commented 6 years ago

Memo for manually switch

Using Runtime + Compiler should be...

// src/main.js
...
new Vue({                       
  el: '#app',
  router,                  
  template: '<App/>',                                     
  components: { App }        
})
// build/webpack.base.conf.js
...
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
    }
  },
...

Using Runtime-only should be...

// src/main.js
...
new Vue({
  el: '#app',
  router,
  render: h => h(App)
})
// build/webpack.base.conf.js
...
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      '@': resolve('src'),
    }
  },
...
thorvn commented 6 years ago

Simple way, change

import Vue from 'vue'

to

import Vue from 'vue/dist/vue.js';

It resolved my issue

michaelwnyc commented 6 years ago

@kensupermen Evan pointed out the solution which is to use an alias other than changing the import. https://github.com/vuejs-templates/webpack/issues/215#issuecomment-238095102

evenstensberg commented 6 years ago

If the config register alias doesn't work, this might be because you are using webpack merge to merge two configurations together. Webpack merge won't pick up resolve.alias

Meekohi commented 6 years ago

I'm pretty lost as to what the actual problem is here, but @thovt93's solution worked for me. I originally had import Vue from "../../../node_modules/vue"; and changed it to import Vue from "vue/dist/vue.js";.

youfoundKim-zz commented 6 years ago

@Meekohi

I can understand. At first glance, it does not make much sense. However, if you take your time and read the link Evan You posted, it should make much more sense.

Essentially, Vue.js ships with two builds:

The compiler takes care of converting template strings to render functions. If you're getting this error, it means that you're trying to use the runtime only build while having one or more string templates in your project.

If you don't have a compilation step (such as webpack w/ vue-loader) and wish to use string templates, just import Vue from 'vue/dist/vue.js' like you're already doing. There's nothing wrong with that.

However, if you do have a compilation step, you might benefit from converting all your string templates to render functions to remove the compiler overhead while using your Vue.js app. This can be done with webpack + vue-loader + only using Single File Components. You will still be able to use templates, they'll just be converted in the compilation step.

If you're unsure on how to render the root Vue.js instance without a string template, this might give you an idea:

// index.js
import Vue from 'vue';
import App from './App.vue';

const app = new Vue({
  el: '#app',
  render: function (h) {
    return h(App);
  }
});
// App.vue
<template>
  <div id="app">
    <p>Does this work?</p>
    <p>{{text}}</p>
  </div>
</template>

<script>
export default {
  data: function () {
    return {
      text: 'Yes it does!'
    }
  }
}
</script>
<!--index.html-->
<html>
  <head></head>

  <body>
    <div id="app"></div>
    <script src="./app.bundle.js"></script>
  </body>
</html>
Meekohi commented 6 years ago

I figured out the source of my confusion -- my project does only have single-file VueJS components, but I am using rails-vue-loader, which after a look at https://github.com/kikyous/rails-vue-loader/blob/master/lib/sprockets/vue/script.rb seems to be just dumping the template in as a string (to my surprise). We are trying to move to webpack, but are "halfway" through, and I guess the vue.js version dropped in by webpack was being used even for the old sprockets Vue instances.

P.S. I had of course already read that link in detail!

vladyslav2 commented 6 years ago

@youfoundKim method you propose with render function for root components always gives me an error:

TypeError: Cannot read property 'matched' of undefined
    at render (vue-router.esm.js:69)
    at createFunctionalComponent (vue.runtime.esm.js:4051)
    at createComponent (vue.runtime.esm.js:4241)
    at _createElement (vue.runtime.esm.js:4411)
    at createElement (vue.runtime.esm.js:4348)
    at vm._c (vue.runtime.esm.js:4480)
    at Proxy.render (App.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/pug-plain-loader!./node_modules/vue-loader/lib??vue-loader-options:8)
    at VueComponent.Vue._render (vue.runtime.esm.js:4532)
    at VueComponent.updateComponent (vue.runtime.esm.js:2783)
    at Watcher.get (vue.runtime.esm.js:3137)

I have no idea why "vue": "2.5.17", "vue-loader": "15.2.6", "vue-router": "3.0.1",

====

Found an issue, I changed router setup (router list in one file, new VueRouter(..) in other and get rid of the error

Meekohi commented 6 years ago

We've now completely removed rails-vue-loader and are just using webpack, but this error persists when using import Vue from "vue". When I break at the warning and look through the stack-trace, it's happening at:

import SidepanelAd from "src/components/sidepanel_ad"
var v = new Vue({ el: "#sidepanelAd", components: {'sidepanel-ad': SidepanelAd} });
<div id='sidepanelAd'>
  <sidepanel-ad ref='sidepanel-ad'/>
</div>

which isn't using string templates (it's defined in a sidepanel_ad.vue file). Any suggestions for getting to the bottom of this issue?

kelp404 commented 6 years ago

@yyx990803 img_2730

nsjames commented 5 years ago

For those without webpack ( babel only ) and using vue-cli use the runtimeCompiler option.

https://cli.vuejs.org/config/#runtimecompiler

Create a vue.config.js file in your project root.

module.exports = {
    runtimeCompiler:true
}
Shadoworker commented 5 years ago

Simple way, change

import Vue from 'vue'

to

import Vue from 'vue/dist/vue.js';

It resolved my issue

This fixed it for me (I'm working with Onsen) . Thanks a lot

BonBonSlick commented 5 years ago

What if vue: 'vue/dist/vue.esm.js', ? Seems work also. What diff with vue: 'vue/dist/vue.js', , also why need resolve extensions? extensions: ['.js', '.vue', '.json'],

laurensiusadi commented 5 years ago

@nsjames it solves the problem on yarn build but not on yarn serve. Is this as intended?

nsjames commented 5 years ago

@laurensiusadi hmm not sure. It should do both.

nicaisa commented 5 years ago

Uncaught Error: Module build failed: SyntaxError: Unexpected token (10:24) at Parser.pp$4.raise (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:2221:15) at Parser.pp.unexpected (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:603:10) at Parser.pp$3.parseExprAtom (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:1822:12) at Parser.parseExprAtom (X:\vip\node_modules\buble\dist\buble.umd.js:656:26) at Parser.pp$3.parseExprSubscripts (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:1715:21) at Parser.pp$3.parseMaybeUnary (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:1692:19) at Parser.pp$3.parseExprOps (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:1637:21) at Parser.pp$3.parseMaybeConditional (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:1620:21) at Parser.pp$3.parseMaybeAssign (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:1597:21) at Parser.pp$3.parseFunctionBody (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:2098:24) at Parser.pp$4.raise (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:2221:15) at Parser.pp.unexpected (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:603:10) at Parser.pp$3.parseExprAtom (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:1822:12) at Parser.parseExprAtom (X:\vip\node_modules\buble\dist\buble.umd.js:656:26) at Parser.pp$3.parseExprSubscripts (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:1715:21) at Parser.pp$3.parseMaybeUnary (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:1692:19) at Parser.pp$3.parseExprOps (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:1637:21) at Parser.pp$3.parseMaybeConditional (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:1620:21) at Parser.pp$3.parseMaybeAssign (X:\vip\node_modules\buble\node_modules\acorn\dist\acorn.js:1597:21) at Parser.pp$3.parseFunctionBody

nicaisa commented 5 years ago

怎么解决

evenstensberg commented 5 years ago

@nicaisa 發送配置

fsarter commented 5 years ago

For those without webpack ( babel only ) and using vue-cli use the runtimeCompiler option.

https://cli.vuejs.org/config/#runtimecompiler

Create a vue.config.js file in your project root.

module.exports = {
    runtimeCompiler:true
}

thanks @nsjames ,it works for me.

nicaisa commented 5 years ago

verbose node v10.13.0 19 verbose npm v6.4.1 20 error code ELIFECYCLE 21 error errno 1 22 error @ development: cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js 22 error Exit status 1 23 error Failed at the @ development script. 23 error This is probably not a problem with npm. There is likely additional logging output above. 24 verbose exit [ 1, true ]

nicaisa commented 5 years ago

这个呢

evenstensberg commented 5 years ago

需要文件

yyynnn commented 5 years ago

my god even init is shitty

reyou commented 5 years ago

$ vue create mySample

does not even create webpack.config.json.

Should we create this explicitly?

sbarbat commented 5 years ago

It happened to me because I included at webpack.config.js some new alias without keeping the ones that Encore added. So I fixed merging the new with the ones that Encore builds with Lodash:

var config = Encore.getWebpackConfig();
config.resolve.alias = _.merge(
    config.resolve.alias, {
        'sylius/ui': path.resolve(__dirname, 'vendor/sylius/sylius/src/Sylius/Bundle/UiBundle/Resources/private/js'),
    });
nolimitdev commented 4 years ago

What is the difference...

in package.json

  "browser": {
    "vue": "vue/dist/vue.common.js"
  }

in webpack.config.js

resolve: {
  alias: {
    vue: 'vue/dist/vue.common.js'
  }
}

Both produces identical build. Which one is good practice?

Nobody mentioned here but for bundlers like browserify or webpack should be used vue/dist/vue.common.js not vue/dist/vue.js because of common is in about 20kB smaller for production build. I think @yyx990803 incorrectly recommends here https://github.com/vuejs-templates/webpack/issues/215#issuecomment-238095102 vue.js instead of vue.common.js for webpack. Note that both vue/dist/vue.common.js and vue/dist/vue.js includes template compiler. See guide here: https://vuejs.org/v2/guide/installation.html#Terms

BonBonSlick commented 4 years ago

I had this issue once again during migrating to vue + typescript, the thing is during template-loader it was removing id="app" or could not mount it due to css modules did not work.

Ahmad-Fathy commented 4 years ago

Now the "runtimerCompiler" has been updated to "runtimeCompiler"