Изменить порядок препроцессоров в Svelte / Sapper

У меня довольно большая проблема с моим приложением sapper. Я использую накопительный пакет с подключаемым модулем svelte-preprocess для преобразования моего scss в css:

const preprocess = sveltePreprocess({
  scss: {
    data: `@import '${join(process.cwd(), "src/styles/main.scss")}';`,
    includePaths: ["node_modules", "src"],
  },
  postcss: {
    plugins: [...],
  },
});

После этого я хочу запустить другой препроцессор, svelte-image, чтобы оптимизировать мои изображения. Проблема здесь в том, что, согласно дизайну препроцессоров, те, которые влияют на разметку, всегда будут запускаться первыми. Это приведет к сбою моего препроцессора изображения, поскольку он встретит файлы scss и не сможет их передать.

Лучшим решением для меня было бы написать собственный препроцессор, который выполняет стилизацию, а затем вызывает библиотеку изображений. В документации есть несколько примеров, но я их не совсем понимаю. Если я попробую этот пример:

const svelte = require('svelte/compiler');

const { code } = await svelte.preprocess(source, [
    {
        markup: () => myPreprocess()
        style: () => imagePreprocess()
    }
], {
    filename: 'App.svelte' // Which file would that be for sapper?
});

Я получаю сообщение об ошибке, что источник неизвестен. Так может ли кто-нибудь указать мне в правильном направлении, как правильно и вызвать этот конкретный препроцессор? Или, может быть, лучшее решение ;-)


person Gh05d    schedule 18.06.2020    source источник


Ответы (1)


tl;dr

Я частично объяснил, как это сделать, и понял, что это будет полезная утилита. Я создал пакет для этого: svelte-sequence-preprocessor.

// rollup.config.js
import svelte from 'rollup-plugin-svelte';
import seqPreprocessor from 'svelte-sequential-preprocessor'
import autoPreprocess from 'svelte-preprocess'
import image from 'svelte-image'
 
export default {
  ...,
  plugins: [
    svelte({
      preprocess: seqPreprocessor([ autoPreprocess(), image() ])
    })
  ]
}

Объяснение

Пример использования препроцессора в документации предназначен для использования функции препроцессора как отдельной утилиты. Чтобы использовать собственный препроцессор со сверткой, вы должны сделать что-то вроде этого:

export default {
  ...,
  plugins: [
    svelte({
      preprocess: {
        markup: ({ content, filename }) => myPreprocess(content)
      }
    })
  ]
}

Примечание. Содержимое, переданное в markup(), будет полным сжатым файлом, представленным в виде строки.

Однако, даже если принять это во внимание, ваше предложение не будет работать так, как вы его описали. Проблема в том, что препроцессоры стилей получают стили только как контент. svelte-image нужен полный компонент Svelte, который и получает markup().

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

export default {
  ...,
  plugins: [
    svelte({
      preprocess: {
        markup: async ({ content, filename }) => {
          const processed = await svelte.preprocess(content, autoPreprocess({ options }), { filename });
          // Handle return value and repeat for other preprocessors
          return {
            code: ...,
            dependencies: ...
          };
      }
    })
  ]
}
person digby280    schedule 21.06.2020
comment
Оно работает. Ты настоящий герой. Пусть солнце светит, куда бы ты ни пошел. - person Gh05d; 22.06.2020