vuejs / babel-plugin-transform-vue-jsx

babel plugin for vue 2.0 jsx
1.85k stars 132 forks source link

Vueify? #91

Closed corysimmons closed 7 years ago

corysimmons commented 7 years ago

I used the vue-cli to create a simple browserify project, then added this plugin. JSX still isn't working in single-file components. Not sure what I'm doing wrong.

{
  "name": "vuejsxtest",
  "description": "A Vue.js project",
  "private": true,
  "scripts": {
    "watchify": "watchify -vd -p browserify-hmr -e src/main.js -o dist/build.js",
    "serve": "http-server -o -s -c 1 -a localhost",
    "dev": "npm-run-all --parallel watchify serve",
    "build": "cross-env NODE_ENV=production browserify -g envify src/main.js | uglifyjs -c warnings=false -m > dist/build.js"
  },
  "babel": {
    "presets": [
      "es2015"
    ],
    "plugins": [
      "transform-vue-jsx"
    ]
  },
  "dependencies": {
    "vue": "^2.0.1"
  },
  "devDependencies": {
    "babel-core": "^6.0.0",
    "babel-helper-vue-jsx-merge-props": "^2.0.2",
    "babel-plugin-syntax-jsx": "^6.18.0",
    "babel-plugin-transform-vue-jsx": "^3.5.0",
    "babel-preset-es2015": "^6.24.1",
    "babelify": "^7.2.0",
    "browserify": "^13.0.1",
    "browserify-hmr": "^0.3.1",
    "cross-env": "^1.0.6",
    "envify": "^3.4.1",
    "http-server": "^0.9.0",
    "npm-run-all": "^2.1.2",
    "uglify-js": "^2.5.0",
    "vueify": "^9.1.0",
    "watchify": "^3.4.0"
  },
  "browserify": {
    "transform": [
      "vueify",
      "babelify"
    ]
  },
  "browser": {
    "vue": "vue/dist/vue.common.js"
  }
}
<template>
  <div id="app">
    {this.msg}
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
    return {
      msg: 'Welcome to Your Vue.js App'
    };
  }
};
</script>

<style scoped>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
}
</style>

image

LinusBorg commented 7 years ago

It seems you have a misunderstanding about how JSX is used - it's used in the javascript, like this:

<script>
export default {
  name: 'app',
  data() {
    return {
      msg: 'Welcome to Your Vue.js App'
    };
  },
  render (h) {
    return (
      <div id="app">
        {this.msg}
      </div>)
  }
};
</script>

<style scoped>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
}
</style>

So there's no <template> anymore...

corysimmons commented 7 years ago

Okay, can there be?

Can <template lang="jsx"> just be a wrapper like:

render (h) {
    return (
      ________________________)
  }
<template lang="jsx">
      <div id="app">
        {this.msg}
      </div>
</template>

...with transform plugins already bundled?

LinusBorg commented 7 years ago
  1. That would be feature request for vue-loader, not this babel-plugin
  2. I don't think this would be worht the effort for us. It's littel to gain for another layer of technical debt in vue-loader, which is already really complex.
corysimmons commented 7 years ago

That's cool. I wonder if it could simply be return required('./Foo.jsx) in there though? 🤔

fwiw, I like Vue for it's single-page component stuff (simplifies all that build stuff), but prefer jsx (like a lot of other people I talk to).

LinusBorg commented 7 years ago

That's cool. I wonder if it could simply be return required('./Foo.jsx) in there though? 🤔

Unfortunately, no. vue-loader first runs the <script> through Babel (or any other transpiler you might have specified, like typescript), then converts what is in <template> to a JS and adds that generated code as the render function to the transpiled JS.

So Babel is already done once vue-loader takes care of <template>, which means we would have to make vue-loader work its tasks in a different order for this special case etc. pp.

fwiw, I like Vue for it's single-page component stuff (simplifies all that build stuff), but prefer jsx (like a lot of other people I talk to).

Well as I demonstrated above, you can sue JSX in an SFC - just not in <template>

corysimmons commented 7 years ago

I appreciate you chatting with me about this.

you can sue JSX in an SFC - just not in