2013-09-23 10 views
21

У меня есть черновой проект подкрепленной YEOMAN-генератор, который я построил на основе generator-webapp, если это какая-либо помощи, вы можете найти его на GitHubКак следует настроить черновое-usemin работать с относительным путем

Проект grunt дает нам задачу grunt-usemin.

Мой проект предполагает создание многоязычного веб-сайта и сохранение чистоты, я решил поместить все страницы, написанные на языке в имени папки, после двухбуквенного короткого кода указанного языка.

| project/ 
|--dist/ 
|----en/ 
|------index.html 
|------404.html 
|------... 
|----fr/ 
|------index.html 
|------404.html 
|------... 

Файлы сделаны из шаблонов Рули и обработаны с assemble. В макете у меня есть строительные блоки для usemin, таких как

<!-- build:css(.tmp) styles/main.css --> 
<link rel="stylesheet" href="../styles/main.css"> 
<!-- endbuild --> 
<!-- build:js scripts/vendor/modernizr.js --> 
<script src="../bower_components/modernizr/modernizr.js"></script> 
<!-- endbuild --> 

Который, в идеальном мире было бы перевести на

<link rel="stylesheet" href="../styles/main.css"> 
<script src="../scripts/vendor/modernizr.js"></script> 

, но вместо этого показывает

<link rel="stylesheet" href="styles/main.css"> 
<script src="scripts/vendor/modernizr.js"></script> 

, который меньше, чем идеал в мое дело. Соответствующая часть Gruntfile.js выглядит следующим образом

useminPrepare: { 
     options: { 
      dest: '<%= yeoman.dist %>' 
     }, 
     html: [ 
      '<%= yeoman.app %>/fr/{,*/}*.html', 
      '<%= yeoman.app %>/en/{,*/}*.html' 
     ] 
    }, 
    usemin: { 
     options: { 
      dirs: ['<%= yeoman.dist %>'] 
     }, 
     html: [ 
      '<%= yeoman.dist %>/fr/{,*/}*.html', 
      '<%= yeoman.dist %>/en/{,*/}*.html' 
     ], 
     css: ['<%= yeoman.dist %>/styles/{,*/}*.css'] 
    } 

Я попытался использовать basedir опцию , установив его в <%= yeoman.dist %>, а также изменение сборки блоков для

<!-- build:css(.tmp) ../styles/main.css --> 
<link rel="stylesheet" href="../styles/main.css"> 
<!-- endbuild --> 
<!-- build:js ../scripts/vendor/modernizr.js --> 
<script src="../bower_components/modernizr/modernizr.js"></script> 
<!-- endbuild --> 

Но, к сожалению, WASN» t, чтобы получить правильный выход.

Более конкретно, первый один ничего не изменится, то второй один имел к папкам scripts и styles выводимый на один уровень слишком высоко в иерархии

| project/ 
|--app/ 
|--dist/ 
|--styles/ 
|--scripts/ 

вместо

| project/ 
|--app/ 
|--dist/ 
|----styles/ 
|----scripts/ 

бы кто-нибудь знает, что делать? Кажется довольно простой usecase, но я не мог найти помощь, которая мне нужна через Google, GitHub или SO ...

+0

любой прогресс в этом? –

+0

Nop, но с тех пор я меняю свой рабочий процесс, я знаю, что вместо глотания я использую глоток, и я не полагаюсь на эту функцию. Существует [gulp-useref] (https://github.com/jonkemp/gulp-useref), который делает то, что сделал grunt-usemin, но я не уверен, что он решает эту конкретную проблему. Поскольку я не полагаюсь на это, я не планирую придумывать свое собственное решение/реализацию. –

+0

Для этого есть исправление: https://github.com/buddhike/grunt-usemin/commit/daefa9eb9ac498a17090008c48fb7392ab82d359#commitcomment-6062680, но, к сожалению, еще никто не объединил его. –

ответ

0

Я видел много вопросов об этом и реальных ответах. В моем проекте я сопоставил папку «dist» со стороной «/ static». Поэтому мне не нужно указывать относительный путь в index.html.

Но тем не менее, проблема остается с usemin

<!-- build:css(.tmp) static/css/main.css --> 
<link rel="stylesheet" href="css/main.css"> 
<!-- endbuild --> 

файл usemin будет записан в dist/static/css/main.css

и HTML, покажет неправильно (но ожидаемый) путь

<link rel="stylesheet" href="static/css/main.css"> 

Единственным обходным решением, которое я нашел, является не касаться блока usemin, запускать grunt и обновлять путь вручную.

+0

Да, я использовал это поведение с успехом, но здесь это действительно актуально. Обновление пути вручную также не является решением, так как, в конце концов, у меня может быть много страниц. Я всегда мог выполнить поиск/замену или [использовать задачу] (https://github.com/yoniholmes/grunt-text-replace), но я действительно озадачен возможностью использования usemin для обработки такого тривиального UseCase. Я уверен, что это возможно или нет, должно быть реализовано. –

+0

согласен, что это не долгосрочное решение. В настоящее время читаем код. Это точно в grunt-usemin/lib/htmlprocessor.js. Существует переменная для разрешения относительного пути от process.cwd(). У большинства задач grunt есть параметр CWD, и для usemin их нет. –

0

Если я понять ваш вопрос правильно, я думаю, вам необходимо установить опцию «корень»:

{ 
    useminPrepare: { 
    html: 'html/index.html', 
    options: { 
    root: 'app' 
    dest: 'dist' 
    } 
    } 
} 

Хотя index.html находится в HTML/папке что поиск файлов будет из приложения/не HTML/

3

Я строил свои собственные Грунтовые леса, и я был расстроен этой проблемой. Мне удалось создать работу вокруг, и я хотел бы поделиться ею с вами.

Я хотел бы использовать собственный пример, чтобы проиллюстрировать причину его проблемы и как мне удалось обойти. Скажем, моя структура каталогов выглядит следующим образом:

| in/ 
+---- pages/ 
| +---- login.html 
+---- js/ 
| +---- s1.js 
| +---- s2.js 
+---- index.html 
| out/ 
| Gruntfile.js 

Где in/ где все мои исходные файлы находятся и out/ является dest каталог, где будут храниться все выходные файлы. Скажем, я хочу, чтобы импортировать s1.js в login.html, я бы написать что-то вроде этого:

<!-- build:js ../js/login.js --> 
<script src="../js/s1.js"></script> 
<!-- endbuild --> 

Здесь, usemin блок выполняет простой строкой замены поэтому выход путь должен быть именно там, где я хочу, чтобы связать выходной файл. Проблема возникает, когда вместо того, чтобы иметь login.js землю в out/js/login.js, useminPrepare в конце концов посадил ее на js/login.js. Причина этого заключается в том, что useminPrepare просто выполняет соединение между dest (out) и выходным путем (../js/login.js), в то время как он должен был выполнить объединение путей относительно того, где находится HTML-файл.

Чтобы обойти эту проблему, заметим, что, если я изложу dest к out/pages который уважающего где login.html найден, он будет работать нормально. НО обратите внимание, что если index.html импортирует js/s2.js аналогичным образом, то это будет прикручено. Поэтому для того, чтобы обойти THAT, нам нужно создать одну цель useminPrepare для index.html с dest: "out" и другую цель для login.html с dest: "out/pages". Следовательно, моя конфигурация useminPrepare теперь выглядит примерно так:

"useminPrepare": { 
    t1: { 
     dest: "out", 
     files: [{src: ["in/*.html"]}], 
     ... 
    }, 
    t2: { 
     dest: "out/pages", 
     files: [{src: ["in/pages/*.html"]], 
     .... 
    } 
} 

Все цели должны будут выполняться. Теперь вы, вероятно, скажете: что, если у меня есть еще больше файлов HTML в других подкаталогах? Означает ли это, что мне нужно будет создать одну цель для каждого каталога, где будут найдены HTML-файлы? Это боль в заднице и глупость. Это является! Согласен. Поэтому я написал очень специальную задачу, чтобы помочь. Я называю это useminPreparePrepare Я намеренно назвал его глупо, потому что это глупо. Я действительно надеюсь избавиться от этой работы примерно в один день, когда люди, использующие usemin, исправляют эту проблему. Как следует из его названия, useminPreparePrepare готовит конфиги для useminPrepare. Его собственные конфигурации отображают useminPrepare (фактически, большинство конфигураций просто копируются) с одним исключением; вам нужно будет добавить свойство src, указывающее на исходный корневой каталог, где находятся все ваши исходные файлы, чтобы он мог определить относительный путь между исходным корнем и файлами HTML. Он будет выполнять, по сути, то, что я упомянул выше. Кроме того, он делает то же самое и для промежуточной директории, поэтому файлы промежуточного уровня не выходят из промежуточного каталога. Вы можете даже иметь несколько целей в useminPreparePrepare, он скопирует параметры для вашей цели.

Чтобы использовать эту функцию, вам сначала нужно будет импортировать useminPreparePrepare. Я не поместил его на npm, поэтому вам придется просто скопировать и вставить его. Я не против. Затем просто переименуйте конфигурацию useminPrepare в useminPreparePrepare и добавьте свойство src.Для приведенного выше примера, src: "in". Затем вам нужно запустить useminPreparePrepare с той целью, которой вы обычно хотели бы, а затем сразу запустить useminPrepare без указания цели, чтобы все цели были запущены. Учитывая приведенный выше пример Grunt конфигурации может выглядеть следующим образом:

"useminPreparePrepare": { 
    html: "in/**/*.html", // All HTML files under in/ and its subdirectories. 
    options: { 
     src: "in", 
     dest: "out", 
     .... 
    } 
}, 
"copy": { 
    html: { // Copies all HTML files from in/ to out/ preserving their relative paths. 
     files: [{ 
       expand: true, 
       cwd: "in", 
       src: ["**/*.html"], 
       dest: "out" 
      } 
     ] 
    } 
}, 
"usemin": { 
    html: "out/**/*.html", // Process all HTML files under out/ and its subdirectories. 
    ... 
} 

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

Надеюсь, это поможет!

0

Я делаю блоки usemin относительно шаблона.

У меня есть структура вроде этого:

app/ - webroot source (devmode) 
app/views/layouts - layouts for server-generated pages (also has usermin tags init) 
app/js - source javascript 

dist/ - production build dir 

я сделать мой HTML выглядеть в приложение/макеты/main.html:

<!-- build:js js/static.min.js --> 
     <script src="../../js/controllers/StaticCtrl.js"></script> 
     <script src="../../js/directives/backImg.js"></script> 
     <script src="../../js/smooth-scroll.js"></script> 
    <!-- endbuild --> 

на разработчика (не usemin, просто подают файлы) «../../» умно просто решает «/», поэтому он все еще работает. Таким образом, вы не нуждаетесь в предварительной обработке во время разработки (с задачами с часами или что-то еще.)

1

Моим решением было вручную изменить плагин grunt-usemin.

Открыть node_modules/grunt-usemin/fileprocessor.js в вашем любимом текстовом редакторе. Где-то около линии 152 находки:

if (assetSearchPath && assetSearchPath.length !== 0) { 
    this.file.searchPath = assetSearchPath; 
} 

и заменить его:

if (assetSearchPath && assetSearchPath.length !== 0) { 
    this.file.searchPath.splice(0, 0, assetSearchPath); 
} 

По умолчанию this.file.searchPath представляет собой массив, содержащий абсолютный путь к текущему файлу. Нет смысла переписывать его с помощью ['dist'], лучше добавить массив с помощью «dist». Таким образом, если элемент не найден в каталоге «dist», можно сделать вывод, что либо путь относительный, либо неправильный. Таким образом, мы используем второе значение из массива searchPath для поиска файла, и если это относительный путь - мы получаем то, что хотели.

1

Я использовал несколько целей, как показано ниже:

useminPrepare: { 
     target1 : { 
       src : ['target1/*.html'], 
       options : { 
        dest: 'out' 
       } 
      }, 

      target2 : { 
       src : ['target2/folder/*.html'], 
       options : { 
        dest: 'out/subfolder' 
       } 
      } 
    }, 

Затем в HTML-блок, который Вы могли бы это: ''

<!-- build:js ../subfolder/script.js --> 
<script src="../subfolder/scripts/main.js></script> 
<!-- endbuild --> 
0
useminPrepare: { 
     loyalty: { 
      src: '<%= loyalty.app %>/Views/index.tpl', 
      options: { 
       dest: '.', 
       flow: { 
        html: { 
         steps: { 
          js: ['concat', 'uglifyjs'], 
          css: ['cssmin'] 
         }, 
         post: {} 
        } 
       } 
      } 
     } 
    }, 
<!-- build:css /resources/v4/css/loyalty/index.css --> 
<link rel="stylesheet" href="../Resources/css/main.css"> 
<link rel="stylesheet" href="../Resources/css/product.css"> 
<link rel="stylesheet" href="../Resources/css/use_code.css"> 
<!-- endbuild --> 

использование как назначение в файле grunt.

4

Я считаю, что вы можете добиться того, что вам нужно таким образом:

Html файла:

<!-- build:css styles/main.css --> 
    <link href='../styles/css/style.css' rel='stylesheet' type='text/css'> 
    <link href='../styles/css/responsive.css' rel='stylesheet' type='text/css'> 

    <link href="../styles/css/skins/welld.css" rel='stylesheet' type='text/css' id="skin-file"> 
    <!-- endbuild --> 

Gruntfile.js

 useminPrepare: { 
      options: { 
       dest: '<%= yeoman.dist %>/' 
      }, 
      html: ['<%= yeoman.app %>/snippets/head.html','<%= yeoman.app %>/snippets/tail.html'] 
     }, 
     usemin: { 
      options: { 
       dirs: ['<%= yeoman.dist %>/'], 
       blockReplacements: { 
        css: function (block) { 
         return '<link rel="stylesheet" href="../' + block.dest + '"/>'; 
        }, 
        js: function (block) { 
         return '<script src="../' + block.dest + '"></script>'; 
        } 
       } 
      }, 
      html: ['<%= yeoman.dist %>/{,*/}*.html'], 
      css: ['<%= yeoman.dist %>/styles/{,*/}*.css'] 
     } 

Готовое решение находится в blockReplacements опции задача ессемина. В основном, задача будет помещать ваши файлы под номером <% = yeoman.dist%>/styles/main.css, тогда как ваш html будет находиться под <% = yeoman.dist%>/en/somefileinEnglish.html, и каждый экземпляр «styles/main.css» в этом файле будет заменен на «../styles/main.css», добавив правильный относительный путь.

В качестве дополнительного совета, если вы строите многоязычный веб-сайт, вы можете рассмотреть grunt-i18n, чтобы перевести ваш файл во время его построения, поэтому вам не нужно поддерживать другой файл html для каждого языка.

0

Я делаю исправление ошибки для относительного пути. https://www.npmjs.com/package/grunt-usemin-fix

Вы можете скопировать и мимо изменения к источнику потребительной мин, чтобы использовать относительный путь