импорт и пакетирование текстовых файлов - PullRequest
0 голосов
/ 01 апреля 2020

Контекст: Я смотрю на использование модулей и пользовательских элементов es6 для нового проекта, использование babel + browserify для переноса и комплектации для производства.

Вопрос: Я бы хотел разделить свои веб-компоненты на файлы css, html и js для разработки, но связать их вместе для производства, чтобы мой файл компонента javascript мог выглядеть примерно так:

import { stuff } from '/node_modules/stuff';

const style = somehowFetch('./example.css');
const template = somehowFetch('./example.html');

customElements.define(
  'hey-there'
  class heyThere extends HTMLElement {
    constructor(){
      super()
    }
    connectedCallback(){
      this.attachShadow({mode:'open'})
        .innerHTML = style + template;
    }
  }
);

Пока что мои единственные идеи:

  • Я мог бы go вернуться к использованию загрузчика AMD, такого как require js, который имеет плагин для текстовых файлов и инструментов для комплектации. Для обычных запросов, хотя я предпочитаю нативный подход, я не убежден в использовании двух разных загрузчиков модулей.

  • Я мог бы запросить ресурсы css & html, используя fetch () и напишите короткий bash сценарий, чтобы заменить эти запросы содержимым файла, которое можно запустить до переноса / объединения.

  • Я мог бы просто добавить путь к css / html файлы в любых произвольных тегах и используйте скрипт bash для замены тегов содержимым файлов. Затем я выполнял бы этот шаг сборки после каждого изменения (я не буду заниматься переносом или сборкой, пока не будет готов к развертыванию)

Есть ли лучшее решение для этого, которого мне не хватает? Иначе, есть ли веские причины не использовать этот подход? Все, что я действительно пытаюсь сделать, это эмулировать структуру компонентов, не отличающуюся от angular приложения.

1 Ответ

0 голосов
/ 03 апреля 2020

Я никогда не находил готового решения для этого, что я нахожу странным; фреймворки, такие как angular отдельные html, css и части js / ts компонента, и это кажется естественной вещью, которую нужно делать с нативными веб-компонентами.

Я свернул свой собственный Простое решение c, которое, кажется, работает, хотя я еще не проводил много испытаний.

В основном я добавил следующее в свою сборку. sh script:

#create temporary copy of directory:
mkdir .tmp && cp -r src/ .tmp/;
#locate component directories and check for sync fetches to be replaced:
find .tmp/component -type d -print0 | while IFS= read -r -d '' FILE;
do
  #if js file in component dir:
  J=$(ls $FILE/*.js 2>/dev/null)
  if [ -n "$J" ]
  then
    echo "File found: $J"
    #for each occurence of requireFile:
    grep "requireFile('.*')" $J | while read -r M ; do
      #retrieve path from sync request:
      if [[ $M =~ requireFile\([\"\'](.*)[\"\']\) ]]
      then
        #get path only:
        P=${BASH_REMATCH[1]};
        #get everything minus 'const xxx ='
        F=${BASH_REMATCH[0]};
        #get full path of requested file:
        FP='.tmp/component/'$P
        #log
        printf "file: $FP required by: $J\n"
        #get file content:
        C=$(cat "$FP");
        #escape the replacement string (i.e. do some confusing stuff i don't understand ):
        IFS= read -d '' -r < <(sed -e ':a' -e '$!{N;ba' -e '}' -e 's/[&/\]/\\&/g; s/\n/\\&/g' <<<"$C")
        RE=${REPLY%$'\n'}
        #replace requireFile request with escaped file content:
        sed -i '' -e "s|$F|\`$RE\`\|g" "$J"
      fi
    done
  fi
done
#transpile and bundle script:
npx browserify .tmp/main.js -o dist/bundle.js -t babelify;
#remove scripts with the #dev tag:
sed -i '' -e "s/<script.*#dev[^>]*><\/script>//g" dist/index.html
#remove temporary directory:
rm -r ./.tmp

Я также добавил файл dev. js, который предоставляет следующую функцию 'requireFile', которая выполняет синхронный запрос xhr:

self.requireFile = s => {
  const r = new XMLHttpRequest();
  r.open('GET', 'component/'+s, false);
  r.send(null);
  if(r.status===200){
    return r.responseText;
  } else {
    throw 'failed:'+r.status;
  }
};

с этими кодами:

const style = requireFile('ex/ex.css');

становится:

const style = `:host{ ... } .etc { ... }`;

до того, как оно будет передано и упаковано.

Самым большим преимуществом этого подхода является то, что ajax пути запроса относятся к индексу. html , но это можно уменьшить, добавив путь к каталогу компонента в функции requireFile, а также в сценарии сборки.

В любом случае, на данный момент на это уже потрачено достаточно времени.

...