Unlock the full potential of ts-transformer-keys in your Vue application

note:

After spending countless hours on this, I finally had a breakthrough today. It turns out that changing transpileOnly to false made all the difference:

  chainWebpack: config => {
    const getCustomTransformers = program => ({
      before: [keysTransformer(program)]
    });
    const transpileOnly = false;

    ["ts", "tsx"].forEach(rule => {
      config.module
        .rule(rule)
        .use("ts-loader")
        .loader("ts-loader")
        .tap(options => Object.assign(options, { getCustomTransformers, transpileOnly }));
    });
  },

This actually worked! I can now see my interface's keys in the console. The only thing bothering me now is whether I'm breaking something by making this change. Is there a better or safer way to achieve the same result?

original post:

I have a hunch that ts-loader's transpileOnly: true, setting may not play nice with transformers. If that's the case, what are my options? Any insights would be greatly appreciated. The transformer causing the issue is Kenji Imamula's ts-transformer-keys

You probably need a good understanding of both webpack and typescript to tackle this problem. If you're like me - working with it but not deep into the core functionality - you might benefit from learning about transformers through this helpful guide: how to write a TypeScript transform plugin

Although I am familiar with webpack, working with Vue 3 for the first time introduced some challenges due to its different configuration setup. To modify the webpack config, you use vue.config.js file along with webpack-merge or webpack-chain. As I needed to tweak the ts loaders, I used chain... alongside a few other configurations. Here's how my vue.config.ts looks like:

const PackageVars = require('./package-vars.webpack-plugin.js')
const keysTransformer = require('ts-transformer-keys/transformer').default

module.exports = {
  configureWebpack: {
    plugins: [PackageVars]
  },

  chainWebpack: config => {
    const getCustomTransformers = program => ({
      before: [keysTransformer(program)]
    })

    ;['ts', 'tsx'].forEach(rule => {
      config.module
        .rule(rule)
        .use('ts-loader')
        .loader('ts-loader')
        .tap(options => Object.assign(options, { getCustomTransformers }))
    })
  },

  pluginOptions: {
    i18n: {
      locale: 'en',
      fallbackLocale: 'en',
      localeDir: 'locales',
      enableInSFC: true
    }
  },

  // additional css configuration goes here
}

Running this generates a webpack.config.js (truncated for brevity) as shown when using vue inspect command:

{
  ...
}

// more webpack configuration follows...

In my code implementation, after appending the demo from the readme to an interface in a .ts file, I expected it to work seamlessly:

import { keys } from "ts-transformer-keys";

export interface FirebaseUser {
  uid: string;
  displayName?: string;
  email?: string;
  phoneNumber?: string;
  emailVerified: boolean;
  isAnonymous?: boolean;
}

const keysOfProps = keys<FirebaseUser>();

console.log({ keysOfProps });

This was supposed to simplify complex factory methods significantly:

export function factoryFirebaseUser(
  data = <Partial<FirebaseUser>>{}
): FirebaseUser {
  if (!data.hasOwnProperty("uid")) {
    data.uid = undefined;
  }
//...

  return data as FirebaseUser;
}

However, upon running npm run serve, I encountered an error:

Uncaught ReferenceError: keys is not defined
. Can anyone help me identify where else I need to include it?

I suspect that the transpileOnly: true, setting in the loader config could be causing this issue. My understanding is that this setting allows separate babel configurations.

Answer №1

Indeed, implementing transpileOnly: true proved to be effective. I took the initiative to submit a bug report requesting clarification on the safety of this practice, and further discussed it on the designated discord channels. In short, no definitive answer was provided by knowledgeable individuals. However, the functionality is operational for now.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to arrange data in angular/typescript in either ascending or descending order based on object key

Hey there! I'm fairly new to Angular and have been working on developing a COVID-19 app using Angular. This app consists of two main components - the State component and the District component. The State component displays a table listing all states, ...

Tips for setting up a listener for when the month changes in an ion-datetime object

When the user selects a different month, I need to update the highlightedDates by calling a query to retrieve all the dates of that specific month. This currently works if the user manually chooses a month and year using the top button, but not when they c ...

Easily Organize Your Data with Kendo React Grid: Rearrange Columns and Preserve Your Custom Layout

Currently, I am working on implementing a Kendo React grid with the option set to reorderable={true} for allowing column reordering. However, I am facing difficulty in determining how to save the new order of columns. Which event should I use to detect whe ...

Rendering content on the server side or pre-rendering in Laravel and Vuejs

I am working on a web application using Laravel 7 and Vuejs2. The website has several important pages including home, about, cities, and help that need to be visible to search engines. I have tried implementing both prerendering and server side rendering b ...

What is preventing me from obtaining a ref when the target is an AsyncComponent in Vue3?

When I import a component using import SearchBarPopper from './xxx': import SearchBarPopper from './search-bar-popper'; export default { components: { SearchBarPopper, }, }; I define the ref name in the template: <search-bar ...

Leveraging an intersection type that encompasses a portion of the union

Question: I am currently facing an issue with my function prop that accepts a parameter of type TypeA | TypeB. The problem arises when I try to pass in a function that takes a parameter of type Type C & Type D, where the intersection should include al ...

Utilizing TypeScript in Kendo UI for JQuery

I have implemented KendoUI for JQuery using TypeScript. Here is an excerpt from my "package.json" file: "dependencies": { "@progress/kendo-theme-material": "^3.19.2", "@progress/kendo-ui": "^2020.3.915 ...

Vue3 and Ionic combined to create a Component that became a reactive object in Vue

Vue is issuing a warning about receiving a Component as a reactive object, which can cause unnecessary performance overhead. The warning suggests using markRaw or shallowRef instead of ref to avoid this issue. However, in my code, I am not explicitly using ...

What is the process for integrating real HTML into my code using Vue?

I'm in the process of developing a deck editor using Vue and I would like to include a list of cards with an "Add" button on each one. Upon clicking the button, I want the card's image and name to show up in a side bar. However, when concatenati ...

Error Type: TypeError when using Mongoose's FindOneAndUpdate function

I am encountering difficulties while trying to implement a findOneAndUpdate query. //UserController UserDAO ['findOneAndUpdate'](userId, {& ...

Effectively managing user access by authorizing levels and securing routes

Below is the code snippet for a protected route where the authentication status is managed by Redux. If there is no token saved in local storage, the isAuthenticated state is set to false. This code snippet is for protecting routes: import PropTypes from & ...

`How can I stop typescript from converting dynamic imports to require()?`

Currently, I am in the process of creating a Discord bot using discord.js. Interestingly, discord.js does not seem to be compatible with ESM modules, which has been causing some complications in my project. As a result, I have resorted to utilizing CommonJ ...

How can you retrieve command line variables within your code by utilizing npm script in webpack?

I'm trying to access command line parameters from an npm script in my "constants.js" file. While I have been able to access parameters in the webpack.config.js file using process.env, it seems to be undefined in my app source files. The scenario con ...

Error TS2393 in Typescript: Multiple function declarations found within a Node/Express application

In my TypeScript node + express application, I have implemented a function in some API routes that looks like this: function cleanReqBody(req) { req.body.createdBy = req.user; req.body.modifiedBy = req.user; req.body.modified = new Date(); } Howeve ...

The promise object is displayed instead of the actual data retrieved from the API call

I am currently working on fetching data from an API and showcasing the name of the returned data on the front end. This function successfully retrieves the data through an API call: async function retrieveData(url){ var _data; let response = await fetch( ...

Is there a way to deactivate the click function in ngx-quill editor for angular when it is empty?

In the following ngx-quill editor, users can input text that will be displayed when a click button is pressed. However, there is an issue I am currently facing: I am able to click the button even if no text has been entered, and this behavior continues li ...

Concatenate all sub-items within a JSON object

I have 2 Objects like this : [ { _id: ObjectId("62990f96345ef9001d9f2dfe"), deletedAt: null, expiredAt: ISODate("2022-06-05T19:29:26.746Z"), dataBarang: [ { vendor: ObjectId("6215dd91139c99003fe4c7cd ...

The router.delete function is not working properly because of an 'UnauthorizedError: Unauthorized'. Can you explain why this is happening?

I am facing an issue with one of the routes in my Vue project. Despite having a consistent structure for all routes, one specific route keeps giving me an unauthorized error. Here are the routes in question: router.get('/:userId/reviews', checkJ ...

Using Angular Ionic for a click event that is triggered by a specific class

I am utilizing Highcharts and would like to click on the legend upon loading. With the use of Angular Ionic, how can I trigger a click on the .highcharts-legend-item class within the ngOnInit() {} method? I am aiming to click on this class as soon as the ...

Trouble seeing span in ion-item in Ionic 2: How can I display plain text instead?

It seems like I may be overlooking something, as I am experiencing an issue with adding a span to an Ion Item, where the span is not being rendered, nor is the div. <ion-card> <ion-card-title> </ion-card-title> <div> < ...