npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

hzinfo-i18n-router-loader

v1.0.10

Published

hzinfo-i18n-router-loader 一键式基于路由实现项目路由文件的国际化 语言包 处理的过程

Downloads

36

Readme

hzinfo-i18n-router-loader

一键式实现项目的国际化 语言包 处理的过程,vue2的loader


HTML

<div>你好,世界</div>

资源文件

//zh_md5
module.exports = {
  "a018615b35588a01": "你好,世界" //key是根据中文生成16的MD5
}
// zh_md5_key_route_map
// 如果 路由下有该文件的key 会自动匹配生成
module.exports = {
	"/demo/list": [
	"a018615b35588a01"
	],
	"/demo/about": [
	
	]
};

页面在中文下展示为

你好世界

在英文下展示为

Hello, world

介绍

该loader的主要目的是将国际化资源与项目代码分离维护,这样我们去查找对应文案的时候更加简单方便,如上述demo所示,我们原文件中不需要去使用 <div>{{ $t('a018615b35588a01') }}</div> 的方式去显示声明国际化,通过loader自动进行替换完成我们的国际化工作,这样对开发查找页面文案之类带来了极大的方便。本组件还支持在vue的props中以及单独的js文件中进行国际化处理。

安装

npm i hzinfo-i18n-router-loader --save-dev

yarn add hzinfo-i18n-router-loader --dev

使用

本组件分为两部分,一部分是cli,目的是为了生成资源文件,一部分是loader,目的是为了替换项目中的中文为国际化的代码,我们最好在打包测试/上线前执行以下cli命令,生成资源文件,然后拷贝一份资源文件给翻译组进行各国语言的翻译,之后将资源文件配置到[email protected]上,再进行打包即可。

cli的使用

cli可使用的所有命令

i18n generate

自动抓取中文

项目根目录执行

npx i18n generate 
对src目录下的vue/js/ts/tsx/jsx文件进行中文提取并生成国际化资源文件

### 跳过中文抓取
js文件和vue文件内被<i18n-ignore (跳过的内容) i18n-ignore>  包括的内容将不会进行抓取

使用实例
js语法
```bash
// <i18n-ignore
const str = "我的世界"
// i18n-ignore>

template内使用

<!-- <i18n-ignore -->
<div>我的世界</div>
<!-- i18n-ignore> -->

loader的使用

loader中需要对vue.config.js 的chainWebpack对象进行配置

chainWebpack: (config) => {
 config.module
      .rule('vue')
      .use('hzinfo-i18n-router-loader')
      .loader('hzinfo-i18n-router-loader')
      .options({
 
        localeFile: path.join(process.cwd(), './src/lang/zh_md5.js') 
      })
      .end()
}
config.module
      .rule('js')
      .exclude
      .add(/node_modules/)
      // .add(/main.js/)
      .end()
      .use('hzinfo-i18n-router-loader')
      .loader('hzinfo-i18n-router-loader')
      .options({
        localeFile: path.join(process.cwd(), 'src/lang/zh_md5.js')
      })
      .end()

main.js 修改子应用 这个方法

 function storeTest(props) {
   props.onGlobalStateChange &&
     props.onGlobalStateChange(
       (value, prev) => {
         console.log(`[onGlobalStateChange - ${props.name}]:`, value, prev);
         if (value.themeName) store.commit('SET_THEME_NAME', value.themeName);
         if (value.fontSize) store.commit('SET_FONT_SIZE', value.fontSize);
         if (value.colorName) store.commit('SET_COLOR_NAME', value.colorName);
         if (value.languageData){
           function setLang(obj){
             const language = getStore({name:'language'})
             console.log(language)
             const zh = i18n.getLocaleMessage(language||'zh')
             i18n.setLocaleMessage(language||'zh',{
               ...zh,
               ...obj,
             })
           }
           setLang(value.languageData)
           Vue.prototype.$forceUpdate()
         }
       },
       true,
     );
   props.setGlobalState &&
     props.setGlobalState({
       ignore: props.name,
       user: {
         name: props.name,
       },
     });
 }

jsonLang.js 与路由文件jsonAes.js 同级 修改package.json 的 script

 "build": "vue-cli-service build && node jsonAes.js && node jsonLang.js",

jsonLang.js的代码

let fs = require('fs');
const path = require('path');
const { name } = require('./package');
const file = require('./node_modules/hzinfo-i18n-router-loader/lib/const')
let CryptoJS = require("crypto-js");
const i18nPath = path.join(process.cwd(), file.config.dir+file.config.file);
const zhMd5KeyRouteMap = require(i18nPath+'_key_route_map.js')
const zhMd5 = require(i18nPath+'.js')


// 初始化一个空对象,用于存储合并后的结果
let mergedResult = {};
console.log(zhMd5KeyRouteMap)
console.log(zhMd5)
// 遍历每个文件
const hasKeys = []

Object.keys(zhMd5KeyRouteMap).forEach(filePath => {
 
  zhMd5KeyRouteMap[filePath].forEach(item=>{
    mergedResult[`${name}${filePath}.${item}`] = zhMd5[item]
    hasKeys.push(item)
  })

});
// 路由未使用的剩余key直接存到子应用上面
Object.keys(zhMd5).filter(key=>!hasKeys.includes(key)).forEach(item=>{
  mergedResult[`${name}.${item}`] = zhMd5[item]
})
console.log(mergedResult);

let key = '1234567890HZINFO1234567890ABCDEF';
let sRoutes =  JSON.stringify(mergedResult);

key = CryptoJS.enc.Utf8.parse(key)
let encryptedData = CryptoJS.AES.encrypt(sRoutes, key, {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
})
encryptedData = encryptedData.ciphertext.toString()

fs.writeFile('./dist/cdn/common/i18n.json', encryptedData, 'utf8', function (err) {
  if (err){
    console.log(err)
  };
});

axios改动

  • axios.interceptors.request.use中加入


// i18n 的 请求头标识传入
  const language = getStore({name:'language'})
  const langs = {
    'zh':'zh_CN',
    'en':'en_US'
  }
  config.headers["Hz-Language"] = langs[language]||language||'zh_CN' ;

原有lang文件的index文件移到i18n文件夹,并且进行修改解决js文件循环引用问题

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang
import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang
import enLocale from '../lang/en'
import zhLocale from '../lang/zh'
function validatenull(val) {
    if (typeof val == 'boolean') {
        return false;
    }
    if (typeof val == 'number') {
        return false;
    }
    if (val instanceof Array) {
        if (val.length == 0) return true;
    } else if (val instanceof Object) {
        if (JSON.stringify(val) === '{}') return true;
    } else {
        if (val == 'null' || val == null || val == 'undefined' || val == undefined || val == '') return true;
        return false;
    }
    return false;
}
const getStore = (params = {}) => {
  const keyName = 'saber-'
  let {
    name,
    debug
  } = params;
  name = keyName + name
  let obj = {},
    content;
  obj = window.sessionStorage.getItem(name);
  if (validatenull(obj)) obj = window.localStorage.getItem(name);
  if (validatenull(obj)) return;
  try {
    obj = JSON.parse(obj);
  } catch{
    return obj;
  }
  if (debug) {
    return obj;
  }
  if (obj.dataType == 'string') {
    content = obj.content;
  } else if (obj.dataType == 'number') {
    content = Number(obj.content);
  } else if (obj.dataType == 'boolean') {
    content = eval(obj.content);
  } else if (obj.dataType == 'object') {
    content = obj.content;
  }
  return content;
}
Vue.use(VueI18n)
const Avue = window.AVUE;
const messages = {
  en: {
    ...enLocale,
    ...elementEnLocale,
    ...Avue.locale.en,
  },
  zh: {
    ...zhLocale,
    ...elementZhLocale,
    ...Avue.locale.zh,
  }
}

const i18n = new VueI18n({
  locale: getStore({ name: 'language' }) || 'zh',
  messages
})

export default i18n

index.html 去掉中文 loading样式稍微调整一下 去掉

 .avue-home__loading {
      height: 50px;
      width: 50px;
    }
.avue-home__main {
      height: 100px;
      user-select: none;
      width: 100%;
      flex-grow: 1;
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
    }

国际化资源配置

此处一定要注意!!!否则是个坑。

国际化的配置一定一定要在所有逻辑之前,建议采用 i18n.js 文件单独配置,然后在入口文件最先引入这个文件即可! 要确保('@/i18n')这个路径可以取到i18n对象

我是将i18n文件单独放到i18n文件夹下的

注意

  • vue的template中不要出現双引号与单引号重复包裹的字符串 例如:
   <template slot-scope="{disabled,size}" slot="templateParamForm">
          <el-input type="textarea" v-model="form.templateParam" :showWordLimit='true' maxlength="1000" :rows="5"
                    placeholder='请输入JSON格式字符串,例如 {"a":1,"b":2}' allow-auth="true"></el-input>
        </template>

这样使用 将会造成打包以及启动项目 报Syntax Error: SyntaxError: Unexpected token 错误

  • 建议字符串的连接用模板字符串方式,这样其中涉及到的一些动态参数也会自动生成 {0} {1} 这样的参数注入
  • import 与import语句之间不要加入中文
例如:
import {getDeviceInstanceList} from '@/api/analysis/new'

const dayDic = [
  {
    dictKey: 0,
    dictValue: '月底'
  },
  ...new Array(31).fill(1).map((item, index) => {
    return {
      dictKey: index + 1,
      dictValue: index + 1 + '日'
    }
  })
]
const monDic = new Array(12).fill(1).map((item, index) => {
  return {
    dictKey: index + 1,
    dictValue: index + 1 + '月'
  }
})
const hoursDic = new Array(24).fill(1).map((item, index) => {
  return {
    dictKey: index,
    dictValue: index + '时'
  }
})
import MyProject from '@/views/components/myProject'
  • npx i18n generate时请手动删除之前生成的2个多语言文件
  • 避免js文件与i18n文件夹下的index.js循环引用