swashata / wp-webpack-script

💥🔥📦👩‍💻 An easy to use, pre configured, hackable webpack setup & development server for WordPress themes and plugins.
https://wpack.io
MIT License
407 stars 57 forks source link

Add Vue.js support #1189

Open michaelw85 opened 3 years ago

michaelw85 commented 3 years ago

As the title explains, it would be nice to have a vue: true option instead of having to manually configure it.

I've got a manual setup working for Vue + TS (with class component and .vue files support) and the following was needed:

NPM: npm i -D vue vue-template-compiler vue-loader vue-class-component ts-loader babel-preset-typescript-vue @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties

wpackio.project.js:

const { VueLoaderPlugin } = require("vue-loader");

module.exports = {
      files: [
        {
            name: "xyz",
            entry: {},
            webpackConfig: {
                module: {
                    rules: [
                        {
                            test: /\.vue$/,
                            loader: "vue-loader",
                            options: {
                                esModule: true,
                            },
                        },
                        {
                            test: /\.ts$/,
                            loader: "ts-loader",
                            options: {
                                appendTsSuffixTo: [/\.vue$/],
                            },
                        },
                    ],
                },
                plugins: [new VueLoaderPlugin()],
            },
        },
....
    tsBabelOverride: (defaults) => ({
        ...defaults,
        presets: ["babel-preset-typescript-vue"],
        plugins: [
            ["@babel/proposal-decorators", { legacy: true }],
            ["@babel/proposal-class-properties", { loose: true }],
        ],
    }),
...
    alias: {
        vue$: "vue/dist/vue.esm.js",
    },

Add a vue-shim.d.ts to your typings folder:

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

Make sure your typings are loaded in your tsconfig.json, something like: "typeRoots": ["node_modules/@types", "typings"]

For a working example using a child theme see: https://github.com/michaelw85/wp-bedrock-wpack-vuejs

swashata commented 3 years ago

Thank you for this. Maybe you can add it to documentation? Since I don't use vue personally I am reluctant to manage its support. Alternately if you can take this job, then I am happy to review your PR :)

michaelw85 commented 3 years ago

Thank you for this. Maybe you can add it to documentation? Since I don't use vue personally I am reluctant to manage its support. Alternately if you can take this job, then I am happy to review your PR :)

Adding this would be nicer than documenting. I definitely am willing to see if I can add it, but it might take some time. To be honest I find it challenging to find the time to work on code in my spare time.

michaelw85 commented 3 years ago

@swashata I've had a little bit of time tonight. I've done a bare minimum implementation, I think I'm at a point where I can test it locally and then have a look at the unit tests. Please see the linked commit, any pointers would be nice since I'm completely new to this codebase.

swashata commented 3 years ago

I took a look. Is ts-loader really necessary? The toolchain support typescript compilation through babel and babel-preset-typescript. Can't that be used instead? We also have support for fork-ts-checker-plugin to report any typing errors.

michaelw85 commented 3 years ago

I took a look. Is ts-loader really necessary? The toolchain support typescript compilation through babel and babel-preset-typescript. Can't that be used instead? We also have support for fork-ts-checker-plugin to report any typing errors.

I was not sure if it's required either. I want to get a working setup first and then try to refactor and see if it can be removed. At least the config telling TS to handle vue files is require.

swashata commented 3 years ago

Maybe you can try and figure out if it works with vue-loader and babel-loader with the TS config that it uses. From the documentation I get the idea that, if the webpack config has something to handle .ts files, then vue-loader uses that. So we just need to push vue-loader before the ts config.

Something like

const vueRules = {
  test: /\.vue$/,
  loader: "vue-loader",
  options: {
    esModule: true,
  },
};

// add it to the list of module rules if this.config.hasVue === true.
michaelw85 commented 3 years ago

Thank you for the input! I haven't been able to continue yet. I would like to try and see if I can find continue on Sunday. I will push updates if there are any and post an update.

michaelw85 commented 3 years ago

@swashata How should I test this locally? I tried using npm link and pointed to the scripts dir. This seems to add the package. I tried running the bootstrap command but it fails, it doesn't prompt for input. I tried an existing config and enabled the new vue setting and run a build. This emits an error ts-loader module can't be found. I've installed the package in the scripts package only, on building it's complaining about the entrypoint package. Should I install packages in a different way than just npm i pkg in the scripts dir?

Sorry, this is probably a noob question and related to using Lerna (this is the first time it's in a project I'm working on).

swashata commented 3 years ago

Hi @michaelw85,

Sorry I got caught up in some other work. So from your findings, it seems like ts-loader is indeed needed for vue-loader to work. Or maybe it is due to some misconfiguration.

In anycase, I think, for now it is better to leave under userland. Extending webpack config is not really a big issue anyway with wpackio.project.js. Once I find some time, I will do another investigation.

In the meanwhile, since I don't use vue at all, a repository of a vue based plugin where I can test the integration would be really helpful.

michaelw85 commented 3 years ago

@swashata I've set up a repo where I have implemented what I described in this thread. A working WordPress setup with Wpack + VueJS hello world example. I've created the WP setup with Bedrock, to get this setup working you will have to composer install, set .env variables, and run npm ci in the child theme. Go to your site in the browser and perform the wp install to create the DB. Login and switch to the child theme I created. Update the wpackio.server.js with your dev URL. npm run start or npm run build and you should have a site with a hello world component at the top of the page.

https://github.com/michaelw85/wp-bedrock-wpack-vuejs

the-sides commented 3 years ago

This has all been fantastic to see and am hopeful for anymore updates. Thanks for all your work @michaelw85 and @swashata!