【问题标题】:i18next + React + Webpack - getFixedT is not a functioni18next + React + Webpack - getFixedT 不是函数
【发布时间】:2019-08-02 04:59:20
【问题描述】:

我在使用 React、i18next 和 Webpack 时遇到了一些问题。我尝试了很多解决方案,但没有一个有效。当我尝试构建我的应用程序时,它会成功构建。但是,当我尝试打开它时,控制台显示错误。我的 webpack.config 和错误堆栈跟踪如下。

webpack.prod.config.js

const webpack = require('webpack');
const path = require('path');
const htmlWebpackPlugin = require("html-webpack-plugin")
const miniCSSExtractPlugin = require("mini-css-extract-plugin")
const terserPlugin = require("terser-webpack-plugin")
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin")
const cleanWebpackPlugin = require("clean-webpack-plugin")

const i18nPlugin = require("i18n-webpack-plugin")
const options = require("../src/controllers/i18n").options
const locales = require("../src/controllers/i18n/locales")

options.backend.loadPath = "." + options.backend.loadPath

const config = {
    mode: "production",
    output: {
        path: path.resolve(__dirname, '../dist'),
        publicPath: "./",
        filename: 'bundle.js'
    },
    resolve: {
        extensions: [" ", ".js", ".jsx"],
        alias: {
            "@components": path.resolve(__dirname, "../src/components"),
            "@views": path.resolve(__dirname, "../src/views")
        }
    },
    optimization: {
        minimizer: [
            new terserPlugin({
                cache: true,
                parallel: true,
                include: /\.(js|jsx)$/
            }),
            new OptimizeCSSAssetsPlugin({})
        ]
    },
    module: {
        rules: [{
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: [{
                    loader: "babel-loader"
                }, {
                    loader: "i18next-loader"
                }]
            },
            {
                test: /\.css$/,
                use: [
                    miniCSSExtractPlugin.loader,
                    {
                        loader: "css-loader",
                    }
                ]
            }, {
                test: /\.(png|jpg|gif)$/,
                use: [{
                    loader: 'file-loader?name=images/[hash].[ext]',
                    options: {
                        name: "assets/images/[hash].[ext]"
                    }
                }]
            }, {
                test: /\.(ttf|woff(2)|eof|svg)$/,
                use: [{
                    loader: "file-loader",
                    options: {
                        name: "assets/fonts/[hash].[ext]",
                    }
                }]
            }
        ],
    },
    plugins: [
        new htmlWebpackPlugin({
            template: path.join(__dirname, "..", "public", "index.html")
        }),
        new miniCSSExtractPlugin({
            filename: "[name].css",
            chunkFilename: "[id].css"
        }),
        new cleanWebpackPlugin("../dist/*", {
            root: __dirname + "../",
            allowExternal: true
        }),
        new i18nPlugin(locales,{
            functionName: "t",
            nested: true
        },true)
    ]
};

module.exports = config;

npm run build 运行正常,没有关于 i18next 的错误。然后,当我打开应用程序时,我得到了这个错误:

bundle.js:33 TypeError: r.getFixedT is not a function
   at L (bundle.js:12)
    at bundle.js:12
    at Xo (bundle.js:33)
    at Ia (bundle.js:33)
    at qi (bundle.js:33)
    at $i (bundle.js:33)
    at jl (bundle.js:33)
    at Cl (bundle.js:33)
    at Pl (bundle.js:33)
    at Ji (bundle.js:33)

希望有人可以帮助我。

【问题讨论】:

    标签: reactjs webpack i18next


    【解决方案1】:

    我找到了我的问题所在。在 i18next 文档中说我应该在 webpack.config.js 中运行 init。

    问题

    我最初的问题是加载语言环境。 i18n 在构建后找不到文件,因为 webpack 无法识别需要 .json 文件的 i18n-xhr-backend。然后,在构建之后,没有翻译文件。然后,我尝试让webpack 处理 i18n,但我遇到了另一个问题,在下一段。

    React 需要将 i18n 实例添加到 i18nextProvider。但是,在我这样做的过程中,React 中没有 i18n 实例可以引用。然后,它找不到翻译功能和其他任何东西。我还找到了 i18nWebpackPlugin,但它也没有解决我的问题,因为它也无法访问 react 中的 i18n 实例。最后,我有两个未解决的问题。

    解决方案

    我的解决方案非常简单。我为development 环境创建了一个新的i18n 配置,并让webpack 处理.json,在构建后将其复制到一个新文件夹中。我将在下面列出 webpack 和 i18n 的配置文件。我的步骤在哪里:

    • i18n.init() 带回i18n/index.js
    • 为每个环境创建不同的选项
    • 配置 webpack 以复制翻译文件
    • 再次导入App.js上的i18n实例

    现在,一切都像魅力一样。

    OBS: 要让 webpack 识别 .json 文件,你需要将它导入某个地方。我在resources.js 文件中做了。

    webpack.prod.config.js

    const webpack = require("webpack");
    const path = require("path");
    const htmlWebpackPlugin = require("html-webpack-plugin");
    const miniCSSExtractPlugin = require("mini-css-extract-plugin");
    const terserPlugin = require("terser-webpack-plugin");
    const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
    const cleanWebpackPlugin = require("clean-webpack-plugin");
    
    const config = {
      mode: "production",
      output: {
        path: path.resolve(__dirname, "../dist"),
        publicPath: "./",
        filename: "bundle.js"
      },
      resolve: {
        extensions: [" ", ".js", ".jsx"],
        alias: {
          "@components": path.resolve(__dirname, "../src/components"),
          "@views": path.resolve(__dirname, "../src/views"),
          "@static": path.resolve(__dirname, "../src/static")
        }
      },
      optimization: {
        minimizer: [
          new terserPlugin({
            cache: true,
            parallel: true,
            include: /\.(js|jsx)$/
          }),
          new OptimizeCSSAssetsPlugin({})
        ]
      },
      module: {
        rules: [
          {
            test: /\.(js|jsx)$/,
            exclude: /node_modules/,
            use: [
              {
                loader: "babel-loader"
              }
            ]
          },
          {
            test: /\.css$/,
            use: [
              miniCSSExtractPlugin.loader,
              {
                loader: "css-loader"
              }
            ]
          },
          {
            test: /\.(png|jpg|gif|ico)$/,
            use: [
              {
                loader: "file-loader?name=images/[hash].[ext]",
                options: {
                  name: "assets/images/[hash].[ext]"
                }
              }
            ]
          },
          {
            test: /\.(ttf|woff2?|eo(f|t)|svg)$/,
            use: [
              {
                loader: "file-loader",
                options: {
                  name: "assets/fonts/[hash].[ext]"
                }
              }
            ]
          },
          {
            test: /\.(json)$/,
            type: "javascript/auto",
            use: [
              {
                loader: "file-loader",
                options: {
                  name: "[folder]/[name].[ext]",
                  outputPath: "assets/locales/"
                }
              }
            ]
          }
        ]
      },
      plugins: [
        new htmlWebpackPlugin({
          template: path.join(__dirname, "..", "public", "index.html")
        }),
        new miniCSSExtractPlugin({
          filename: "[name].css",
          chunkFilename: "[id].css"
        }),
        new cleanWebpackPlugin("../dist/*", {
          root: __dirname + "../",
          allowExternal: true
        })
      ]
    };
    module.exports = config;
    
    

    i18n/index.js

    const i18n = require("i18next");
    const initReactI18next = require("react-i18next").initReactI18next;
    const langDetector = require("i18next-browser-languagedetector");
    const backend = require("i18next-xhr-backend");
    const moment = require("moment");
    
    const resources = require("../../static/locales");
    
    /*
    
    Other codes...
    
    */
    
    i18n.use(langDetector).use(initReactI18next);
    
    var options;
    
    switch (process.env.NODE_ENV) {
      case "test":
        options = {
          whitelist: ["en", "pt"],
          fallbackLng: "en",
          resources,
          ns: "translation",
          defaultNS: "translation",
          interpolation: {
            format: function(value, format, lng) {
              if (value instanceof Date) return moment(value).format(format);
              return value.toString();
            }
          }
        };
        break;
      case "production":
        i18n.use(backend);
        options = {
          whitelist: ["en-US", "pt-BR"],
          fallbackLng: {
            pt: ["pt-BR"],
            en: ["en-US"],
            default: ["en"]
          },
          ns: ["button", "common", "lng", "info"],
          defaultNS: "common",
          backend: {
            loadPath: "./assets/locales/{{lng}}/{{ns}}.json"
          },
          detection: {
            order: ["querystring", "cookie", "navigator", "localStorage"]
          },
          lookupQuerystring: "lng",
          caches: ["localStorage", "cookie"],
          react: {
            wait: true
          },
          interpolation: {
            format: function(value, format, lng) {
              if (format === "uppercase") return value.toUpperCase();
              if (value instanceof Date) return moment(value).format(format);
              return value;
            }
          }
        };
        break;
      case "development":
        i18n.use(backend);
        options = {
          whitelist: ["en-US", "pt-BR"],
          fallbackLng: {
            pt: ["pt-BR"],
            en: ["en-US"],
            default: ["en"]
          },
          ns: ["button", "common", "lng", "info"],
          defaultNS: "common",
          backend: {
            loadPath: "./src/static/locales/{{lng}}/{{ns}}.json"
          },
          detection: {
            order: ["querystring", "cookie", "navigator", "localStorage"]
          },
          lookupQuerystring: "lng",
          caches: ["localStorage", "cookie"],
          react: {
            wait: true
          },
          interpolation: {
            format: function(value, format, lng) {
              if (format === "uppercase") return value.toUpperCase();
              if (value instanceof Date) return moment(value).format(format);
              return value;
            }
          }
        };
        break;
    }
    
    i18n.init(options);
    
    module.exports = i18n;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-04
      • 2021-01-27
      相关资源
      最近更新 更多