Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Future: Support Vue Single File Component, deprecate .vue.html compilation #123

Closed
ryanelian opened this issue Mar 26, 2018 · 3 comments
Closed

Comments

@ryanelian
Copy link
Owner

ryanelian commented Mar 26, 2018

Obviously a breaking change. ☢️ 🚨

When

Currently vetur cannot provide intellisense for members of a component class. vuejs/vetur#145

Accelist dev team prefers the purity of current module ecosystem (TS, JS, HTML, JSON; hence the makeshift .vue.html file). However, this will change if suddenly vetur adds rich intellisense:

  • instapack will be modified to enable .vue file compilation!

    • To encourage migrations of older projects for improved maintainability, .vue.html file support will be deprecated.
  • VS Code + Vetur will be the preferred IDE for developing a Single-Page Application.

What

The below example reflects the new vue template if Vue Single Component compilation is supported. Currently:

  • compiler and framework are not exposed by the vetur auto-complete.

  • Hovering over compiler and framework does not tell the data types of respective variables. Neither when using directives such as v-for.

Hello.vue

<template>
  <div>
      <h1>Hello from {{ compiler }} and {{ framework }}!</h1>
  </div>
</template>

<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";

@Component({
  props: ["framework", "compiler"]
})
export default class Hello extends Vue {
  framework: string;
  compiler: string;
}
</script>

vue-shim.d.ts

declare module "*.vue" {
    import Vue from "vue";
    export default Vue;
}

// allows:
import Hello from './components/Hello.vue';

Changes Required for the TS Build Tool

yarn add vue-loader -E

get typescriptLoader() {
    let options = this.tsconfigOptions;
    options.sourceMap = this.flags.sourceMap;
    options.inlineSources = this.flags.sourceMap;

    return {
        loader: 'core-typescript-loader',
        options: {
            compilerOptions: options
        }
    };
}

get typescriptWebpackRules() {
    return {
        test: /\.tsx?$/,
        use: [this.typescriptLoader]
    };
}

get vueWebpackRules() {
    return {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
            loaders: {
                'ts': [this.typescriptLoader]
            }
        }
    }
}

Changes Required for The TS Checker Tool

Include .vue files regardless it being imported or not. (We cannot detect import due to vue-shim.d.ts)

However we include them as .vue.ts to enable checks. Obviously, this file is imaginary / virtual / phantom.

When reading the file, we read the .vue counterpart, strip all codes before <script lang="ts"> and strip all codes after </script>

This essentially turns the .vue file into a normal TypeScript file. That way, we can still check for errors in parallel with the actual compilation!

In case there are future frameworks doing this kind of 💩 again, develop the feature as a plugin system.

@ryanelian
Copy link
Owner Author

Feature is implemented by #128 but compilation not yet enabled.

@ryanelian ryanelian changed the title Future: Support Vue Single File Component, drop .vue.html compilation Future: Support Vue Single File Component, deprecate .vue.html compilation Apr 16, 2018
@ryanelian
Copy link
Owner Author

ryanelian commented Apr 16, 2018

Compilation was enabled in vue-sfc branch. However, there are actual issues with Vetur and vue-loader themselves:

Vue Export Specification

It appears that there are 3 known ways of exporting a Vue component:

Plain Old JavaScript Object

export default {
    render: undefined,
    staticRenderFns: undefined,
};

Output code is the same as input code

Vue Extend

import Vue from 'vue'
export default Vue.extend({
    render: undefined,
    staticRenderFns: undefined,
})

Output code is the same as input code

Vue Class Component

Input:

import Vue from 'vue';
import Component from 'vue-class-component';

@Component({
    render: undefined,
    staticRenderFns: undefined,
})
export default class extends Vue {
}

Output:

import * as tslib_1 from "tslib";
import Vue from 'vue';
import Component from 'vue-class-component';
var default_1 = /** @class */ (function (_super) {
    tslib_1.__extends(default_1, _super);
    function default_1() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    default_1 = tslib_1.__decorate([
        Component({
            render: undefined,
            staticRenderFns: undefined,
        })
    ], default_1);
    return default_1;
}(Vue));
export default default_1;

@ryanelian
Copy link
Owner Author

Feature is live in instapack@beta

The next release will wait for vue-loader to reach 15 GA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant