Как загрузить несколько файлов YAML одновременно в JavaScript

#javascript #typescript #vue.js #yaml

#javascript #typescript #vue.js #yaml

Вопрос:

Я написал скрипт Ruby, который разбивает один большой файл YAML (называемый travel.yaml ), который содержит список ключей страны и информацию, на отдельные файлы для каждой страны.

 data = YAML.load(File.read('./src/constants/travel.yaml'))

data.fetch('countries').each do |key, value|
  File.open("./src/constants/countries/#{key}.yaml", 'w') { |file| file.write({ key => value }.to_yaml) }
end
  

Оформление каждого файла следующим образом:

 ---
BA:
  sources:
    domestic:
    - Wearing masks and social distancing (a minimum of 2 metres) are [mandatory in
      all public places](https://www.oecd.org/south-east-europe/COVID-19-Crisis-in-Bosnia-and-Herzegovina.pdf).
    inbound:
    - The BiH Council of Ministers has announced that it will allow entry to the citizens
      of Croatia, Serbia, and Montenegro as of June 1, 2020. There is [still a ban
      to entry for non-resident foreign nationals.](https://ba.usembassy.gov/covid-19-information/)
    visa_quarantine:
    - Both the Republika Srpska and the Federation have [abolished self-isolation
      measures for people entering BiH.](https://ba.usembassy.gov/covid-19-information/).
  travel:
    domestic: partial
    inbound: partial
    inbound_allowed:
    - HR
    - RS
    - ME

  

Перед разделением travel.yaml вот как это использовалось:

 import TravelDefaults from '@/constants/travel.yaml';

export const Travel = TravelDefaults;

const { countries, checked_on } = Travel;

  

Теперь я хотел бы загрузить все отдельные файлы YAML сразу и использовать их вместо этого (без необходимости импортировать каждый файл отдельно).

Как я могу это сделать? Это должно быть сделано в VUE и с помощью Typescript.

Комментарии:

1. вы могли бы объединить их в один большой файл YAML (называемый travel.yaml )

Ответ №1:

 const yaml = require('js-yaml');
const mergeYaml = require('merge-yaml');
const fs = require('fs');

const travelMerger = () => {
  const basePath = './src/constants/';

  const countryFiles = fs.readdirSync(`${basePath}countries/`);

  const filesWithDir = countryFiles.map((file) => `${basePath}countries/${file}`);

  const countriesYaml = mergeYaml(filesWithDir);

  const yamlStr = yaml.safeDump(countriesYaml);

  fs.writeFileSync(`${basePath}travelMerged.yaml`, yamlStr, 'utf8');
};

module.exports = travelMerger;
  

Это работает, но, к сожалению, не в Vue с TypeScript.

Ответ №2:

Если вы не возражаете против статического решения во время компиляции, вы можете сделать это с помощью webpack require.context (docs) и загрузчика yaml.

Пример

С помощью vue-cli-plugin-yaml.

Предполагая, что ваши файлы yml расположены в src/constants/countries/*.yml , вы можете использовать следующий код для получения каждого объекта JS из файлов yaml с использованием вычисляемого метода с именем countries :

 <template>
  <div id="app">
    <div
      v-for="country in countries"
      :key="country.key"
      class="country"
    >
      <h1>{{country.key}}</h1>
      <hr />
      <h2>{{country.sources.domestic[0]}}</h2>
    </div>
  </div>
</template>

<script lang="ts">
import { Vue } from 'vue-property-decorator'
export default class App extends Vue {
  get countries () {
    const requireContext = require.context(
      './constants/countries',
      true,
      /(.*).yml/
    )
    return requireContext.keys().map((fileName) => {
      const key: string = fileName.split('.')[1].replace('/', '')
      return {
        key: key,
        ...requireContext(fileName)[key]
      }
    })
  }
}
</script>

<style>
#app {
  text-align: center;
  margin-top: 60px;
}
.country{
  border:1px solid black;
  margin:20px;
}
</style>
  

пример с некоторыми фиктивными файлами