如何使用Vue获得ts-transformer-keys

问题描述 投票:0回答:1

编辑:

现在,我感觉像个白痴……自昨天晚上以来,我一直在从事此工作。今天我意识到我可以测试将transpileOnly解析为false:

  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 }));
    });
  },

而且..确实有效。我在控制台中看到界面的键。我现在唯一的问题是-我这样做会破坏什么?如果我这样做不安全,还有其他更好的方法吗?

原件:

此刻,我的怀疑(来自上一段)是ts-loadertranspileOnly: true,选项与变压器不兼容...如果是这样,那么有什么可以做的吗?只需确认或否认我的想法,就会很棒。有问题的变压器是Kenam Imamula的ts-transformer-keys

我认为您需要熟悉webpack和打字稿,才能正常工作。如果您像我一样,专业地使用它但不参与核心功能,那么您可能会喜欢以下关于变压器的入门知识:how to write a TypeScript transform plugin

我在wepack方面非常有能力,因此我希望能够正常工作。但是,我第一次使用vue 3,并且webpack是..不同。您使用vue.config.js设置了一个块,以使用webpack-merge或webpack-chain修改webpack配置。由于我想改变ts加载程序(我假设),因此我使用chain ..我进行了一些其他配置更改,所以我的vue.config.ts看起来像这样:

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
    }
  },

  css: {
    loaderOptions: {
      sass: {
        prependData: `@import "@/styles/global.scss";`
      }
    }
  }
}

并生成一个webpack.config.js(据vue inspect的报告,此方法已被取消,由于stackoverflow中的字符限制,大部分删除了与CSS相关的编译):

{
  mode: 'development',
  context: '/Users/me/Public/project',
  node: {
    setImmediate: false,
    process: 'mock',
    dgram: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
    child_process: 'empty'
  },
  //...
  resolveLoader: {
    modules: [
      '/Users/me/Public/project/node_modules/@vue/cli-plugin-typescript/node_modules',
      '/Users/me/Public/project/node_modules/@vue/cli-plugin-babel/node_modules',
      'node_modules',
      '/Users/me/Public/project/node_modules',
      '/Users/me/Public/project/node_modules/@vue/cli-service/node_modules'
    ]
  },
  module: {
    noParse: /^(vue|vue-router|vuex|vuex-router-sync)$/,
    rules: [
      /* config.module.rule('vue') */
      {
        test: /\.vue$/,
        use: [
          {
            loader: '/Users/me/Public/project/node_modules/cache-loader/dist/cjs.js',
            options: {
              cacheDirectory: '/Users/me/Public/project/node_modules/.cache/vue-loader',
              cacheIdentifier: '1fc0539f'
            }
          },
          {
            loader: '/Users/me/Public/project/node_modules/vue-loader/lib/index.js',
            options: {
              compilerOptions: {
                whitespace: 'condense'
              },
              cacheDirectory: '/Users/me/Public/project/node_modules/.cache/vue-loader',
              cacheIdentifier: '1fc0539f'
            }
          }
        ]
      },
      //...
      /* config.module.rule('js') */
      {
        test: /\.m?jsx?$/,
        exclude: [
          function () { /* omitted long function */ }
        ],
        use: [
          {
            loader: '/Users/me/Public/project/node_modules/cache-loader/dist/cjs.js',
            options: {
              cacheDirectory: '/Users/me/Public/project/node_modules/.cache/babel-loader',
              cacheIdentifier: '0fff5c38'
            }
          },
          {
            loader: '/Users/me/Public/project/node_modules/babel-loader/lib/index.js'
          }
        ]
      },
      /* config.module.rule('eslint') */
      {
        enforce: 'pre',
        test: /\.(vue|(j|t)sx?)$/,
        exclude: [
          /node_modules/,
          '/Users/me/Public/project/node_modules/@vue/cli-service/lib'
        ],
        use: [
          {
            loader: '/Users/me/Public/project/node_modules/eslint-loader/index.js',
            options: {
              extensions: [
                '.js',
                '.jsx',
                '.vue',
                '.ts',
                '.tsx'
              ],
              cache: true,
              cacheIdentifier: '5749dfb1',
              emitWarning: false,
              emitError: false,
              eslintPath: '/Users/me/Public/project/node_modules/eslint',
              formatter: function () { /* omitted long function */ }
            }
          }
        ]
      },
      /* config.module.rule('ts') */
      {
        test: /\.ts$/,
        use: [
          {
            loader: '/Users/me/Public/project/node_modules/cache-loader/dist/cjs.js',
            options: {
              cacheDirectory: '/Users/me/Public/project/node_modules/.cache/ts-loader',
              cacheIdentifier: 'b1785fd2'
            }
          },
          {
            loader: '/Users/me/Public/project/node_modules/babel-loader/lib/index.js'
          },
          {
            loader: 'ts-loader',
            options: {
              transpileOnly: true,
              appendTsSuffixTo: [
                '\\.vue$'
              ],
              happyPackMode: false,
              getCustomTransformers: program => ({
                before: [keysTransformer(program)]
              })
            }
          }
        ]
      },
      /* config.module.rule('tsx') */
      {
        test: /\.tsx$/,
        use: [
          {
            loader: '/Users/me/Public/project/node_modules/cache-loader/dist/cjs.js',
            options: {
              cacheDirectory: '/Users/me/Public/project/node_modules/.cache/ts-loader',
              cacheIdentifier: 'b1785fd2'
            }
          },
          {
            loader: '/Users/me/Public/project/node_modules/babel-loader/lib/index.js'
          },
          {
            loader: 'ts-loader',
            options: {
              transpileOnly: true,
              happyPackMode: false,
              appendTsxSuffixTo: [
                '\\.vue$'
              ],
              getCustomTransformers: program => ({
                before: [keysTransformer(program)]
              })
            }
          }
        ]
      },
      /* config.module.rule('i18n') */
      {
        resourceQuery: /blockType=i18n/,
        type: 'javascript/auto',
        use: [
          {
            loader: '@kazupon/vue-i18n-loader'
          }
        ]
      }
    ]
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendors: {
          name: 'chunk-vendors',
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          chunks: 'initial'
        },
        common: {
          name: 'chunk-common',
          minChunks: 2,
          priority: -20,
          chunks: 'initial',
          reuseExistingChunk: true
        }
      }
    },
    minimizer: [
      {
        options: {
          test: /\.m?js(\?.*)?$/i,
          chunkFilter: () => true,
          warningsFilter: () => true,
          extractComments: false,
          sourceMap: true,
          cache: true,
          cacheKeys: defaultCacheKeys => defaultCacheKeys,
          parallel: true,
          include: undefined,
          exclude: undefined,
          minify: undefined,
          terserOptions: {
            compress: {
              arrows: false,
              collapse_vars: false,
              comparisons: false,
              computed_props: false,
              hoist_funs: false,
              hoist_props: false,
              hoist_vars: false,
              inline: false,
              loops: false,
              negate_iife: false,
              properties: false,
              reduce_funcs: false,
              reduce_vars: false,
              switches: false,
              toplevel: false,
              typeofs: false,
              booleans: true,
              if_return: true,
              sequences: true,
              unused: true,
              conditionals: true,
              dead_code: true,
              evaluate: true
            },
            mangle: {
              safari10: true
            }
          }
        }
      }
    ]
  },
  plugins: [
    /* config.plugin('vue-loader') */
    new VueLoaderPlugin(),
    /* config.plugin('define') */
    new DefinePlugin(
      {
        'process.env': {
          NODE_ENV: '"development"',
          VUE_APP_I18N_LOCALE: '"en"',
          VUE_APP_I18N_FALLBACK_LOCALE: '"en"',
          BASE_URL: '"/"'
        }
      }
    ),
    /* config.plugin('case-sensitive-paths') */
    new CaseSensitivePathsPlugin(),
    /* config.plugin('friendly-errors') */
    new FriendlyErrorsWebpackPlugin(
      {
        additionalTransformers: [
          function () { /* omitted long function */ }
        ],
        additionalFormatters: [
          function () { /* omitted long function */ }
        ]
      }
    ),
    /* config.plugin('html') */
    new HtmlWebpackPlugin(
      {
        templateParameters: function () { /* omitted long function */ },
        template: '/Users/me/Public/project/public/index.html'
      }
    ),
    /* config.plugin('pwa') */
    new HtmlPwaPlugin(
      {
        name: 'project'
      }
    ),
    /* config.plugin('preload') */
    new PreloadPlugin(
      {
        rel: 'preload',
        include: 'initial',
        fileBlacklist: [
          /\.map$/,
          /hot-update\.js$/
        ]
      }
    ),
    /* config.plugin('prefetch') */
    new PreloadPlugin(
      {
        rel: 'prefetch',
        include: 'asyncChunks'
      }
    ),
    /* config.plugin('copy') */
    new CopyPlugin(
      [
        {
          from: '/Users/me/Public/project/public',
          to: '/Users/me/Public/project/dist',
          toType: 'dir',
          ignore: [
            '.DS_Store',
            {
              glob: 'index.html',
              matchBase: false
            }
          ]
        }
      ]
    ),
    /* config.plugin('fork-ts-checker') */
    new ForkTsCheckerWebpackPlugin(
      {
        vue: true,
        tslint: false,
        formatter: 'codeframe',
        checkSyntacticErrors: false
      }
    ),
    {
      definitions: {
        'process.env': {
          PACKAGE_VERSION: '"2.0.0"',
          PACKAGE_NAME: '"project"'
        }
      }
    }
  ],
  entry: {
    app: [
      './src/main.ts'
    ]
  }
}

在我的代码中,我将自述文件中的演示附加到了我想使用的接口上(这是一个.ts文件,而不是一个.vue文件,因此我确实期望它能正常工作的一半):

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 });

这将简化/减少工厂方法的负担,如下所示:

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

  return data as FirebaseUser;
}

但是当我运行npm run serve时,我会得到:Uncaught ReferenceError: keys is not defined ..您能帮我找出我还需要添加的地方吗?

我想知道加载程序配置中所需的transpileOnly: true,选项是否是罪魁祸首?我相信这是为了使babel可以单独配置。

typescript vue.js webpack vue-loader
1个回答
0
投票

是的,添加transpileOnly:true确实有效。我打开了一个错误报告,询问有关该命令是否安全的详细信息,然后在正式的不和谐服务器上进行了追踪:tl-dr任何活跃的人都不知道。但至少它可以工作。

© www.soinside.com 2019 - 2024. All rights reserved.