Search
Write a publication
Pull to refresh

Создание шаблона проекта HTML-сайта в Visual Studio

Level of difficultyMedium

У меня периодически возникает необходимость сделать простой html/js/css сайт, и я для себя сделал шаблон проекта простого html сайта. Этим проектом и методикой его создания хочу с вами поделиться.


Создаём на диске папку под проект будущего шаблона сайта.

Создаём или копируем первичное наполнение. У меня получилась вот такая структура из папок и файлов:

В Visual Studio открываем проект как WEB-сайт: FILE => Open => Web Site и указываем подготовленную папку:

При открытии сайта VS (Visual Studio) может предложить проапгрейдить проект до .NET Framework 4.8 (или другой, какой установлен) - соглашаемся, даже с учётом того, что никакого до этого не было:

 На этом этапе в проект студией добавляется файл Web.config.

Сохраняем VS Solution для дальнейшей работы и переходим в проект. Не сохранять solution можно, но я бы строго не рекомендовал, если в дальнейшем планируете работать с этим проектом полноценно.

Наполняем необходимым для шаблона функционалом. Я «натянул» простенький bootstrap 5 html/js/css/ (тут @kustof/SimpleSiteTemplate всё видно )).

Можно добавить необходимый файл средствами VS. Давайте добавим файл стилей. Add=>Add New Item. Набор шаблонов в этом режиме ограничен, поэтому просто пишем имя файла сразу с расширением, или можно переключиться на компактный вид:

Также на этом этапе рекомендую добавить папки, которые вы планируете использовать в будущих проектах.

Преимущество такого типа шаблона проекта HTML-сайта, как я писал выше, что можно, как и с любым другим типом компилируемого проекта осуществлять сборку (Build), отладку (Debug) и т.д. Поэтому смело жмём Ctrl+F5. Сайт откроется в браузере по умолчанию, убеждаемся, что для шаблона всё работает хорошо, и переходим к следующему шагу.

Сейчас у нас только одна конфигурация проекта - Debug. Я обычно добавляю Release и Publish. Добавим для примера Release. BUILD => Configuration Manager, далее Active Solution Configuration => New => Добавляем конфигурацию с копированием настроек:

И получаем:

Добавим публикацию BUILD => Publish Web App. Я в итоге, пришёл к следующей конфигурации:

После первой публикации создаётся следующая ветка в solution’е:

Мы к ней ещё вернёмся.

Создаём шаблон из проекта (https://learn.microsoft.com/ru-ru/visualstudio/ide/how-to-create-project-templates?view=vs-2022). Делаем экспорт шаблона: PROJECT => EXPORT TEMPLATE, заполняем необходимые поля:

 

Если по первому скрину всё понятно, то по заполнению второго прокомментирую скрином ниже. Этот скрин сделал при добавлении нового проекта, выбора шаблона:

  • Template name - имя шаблона. При создании проекта отображается в поле под номером 1;

  • Template description - необязательное поле. Краткое описание шаблона. В скрине создания проекта под номером 2.

  • Icon Image-иконка шаблона. На скрине под номером 3.

  • Preview Image-иконка, символизирующая шаблон. Необязательное поле. Есть в старых версиях студии.

  • Automatically import the template into Visual Studio и Display an explorer window on the output files folder-соответственно автоматически импортировать шаблон, и открыть папку с готовым шаблоном.

Проект будет экспортирован в ZIP-файл и помещен в указанное выходное расположение, а также (если установлен соответствующий флажок) импортирован в Visual Studio.

Чтобы найти шаблон в диалоговом окне создания проекта, можно использовать поиск по имени или прокрутку списка.

Microsoft говорит: "Фильтрация на основе языка или типа проекта в настоящее время невозможна для пользовательских шаблонов". Но, есть нюансы.

Открываем ZIP-архив экспортированного шаблона и видим среди всего прочего файл MyTemplate.vstemplate. Переименовываем с названием шаблона - SimpleSite.vstemplate. Открываем, и видим среди прочего раздел такого вида:

<TemplateData>
  <Name>SimpleSite</Name>
  <Description>Simple HTML, CSS, JS Web Site. With Bootstrap template</Description>
  <ProjectType>Web</ProjectType>
  <ProjectSubType>CSharp</ProjectSubType>
  <SortOrder>1000</SortOrder>
  <CreateNewFolder>true</CreateNewFolder>
  <DefaultName>SimpleSite</DefaultName>
  <ProvideDefaultName>true</ProvideDefaultName>
  <LocationField>Enabled</LocationField>
  <EnableLocationBrowseButton>true</EnableLocationBrowseButton>
  <Icon>__TemplateIcon.ico</Icon>
</TemplateData>

Такой он получается сгенерированный VS. Вносим в него свои коррективы:

<TemplateData>
	<Name>SimpleSite</Name>
	<Description>Simple HTML, CSS, JS Web Site. With Bootstrap template</Description>
	<ProjectType>CSharp</ProjectType>
	<ProjectSubType>Web</ProjectSubType>
	<TemplateGroupID>Web</TemplateGroupID>
	<SortOrder>1000</SortOrder>
	<CreateNewFolder>true</CreateNewFolder>
	<DefaultName>SimpleSite</DefaultName>
	<ProvideDefaultName>true</ProvideDefaultName>
	<LanguageTag>csharp</LanguageTag>
	<PlatformTag>linux</PlatformTag>
	<PlatformTag>macos</PlatformTag>
	<ProjectTypeTag>web</ProjectTypeTag>
	<LocationField>Enabled</LocationField>
	<EnableLocationBrowseButton>true</EnableLocationBrowseButton>
	<Icon>__TemplateIcon.ico</Icon>
	<PreviewImage>__PreviewImage.jpeg</PreviewImage>
</TemplateData>

Теперь  фильтрация на основе языка или типа проекта работает.

Есть несколько путей импортировать шаблон проекта в студию. Например:

Поставить галочку при экспорте шаблона (см. выше); Просто положить архив шаблона в папку \Documents\Visual Studio 2022\Templates\ProjectTemplates. Как тут указано;

Причём, в какую из вложенных папок вы положите, разницы на мой взгляд, нет. Я размещаю архив в корне.

Пробуем создать проект по шаблону:

Как видим всё создаётся, компилируется, в нужную папку публикуется, в браузере через IIS Express отображается:

Чего хотели, сделали!

Но делаем для себя же ). Само-собой разумеющееся работа сайта с JavaScript - значит будет разумным добавить поддержку TypeScript из коробки. Устанавливаем nuget пакет Microsoft.TypeScript.MSBuild, добавляем в корень проекта tsconfig.json, я добавил такое содержимое:

{
  "compilerOptions": {
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": false,
    "sourceMap": true,
    "target": "ES2022",
    "module": "ESNext",
    "allowJs": false,
    "moduleResolution": "Node",
    "typeRoots": [ "wwwroot/lib/@types/" ],
    "lib": [ "esnext", "dom" ]
  },
  "exclude": [
    "node_modules",
    "obj",
    "bin"
  ],
  "compileOnSave": true
}

Добавим ветку с TS файлом, добавим пару функций, компилируем, и убеждаемся, что JS файл генерируется:

Здорово! Облегчили себе жизнь при создании проектов HTML-сайтов.

Что мы можем сделать ещё? Использовать разрозненные и не минифицированные файлы js и css в настоящее время не комильфо, да и любой PageSpeed сразу заругается... Исправляем.

Ставим из магазина, если ещё не установлено расширение «Bundler & Minifier 2022+» (https://marketplace.visualstudio.com/items?itemName=Failwyn.BundlerMinifier64).

Правой кнопкой в solution на любом css или js файле => Bundler & Minifier => Minify File

Будет сгенерирована минифицированная версия файла, и добавлен файл bundleconfig.json с примерным содержимым:

[
  {
  "outputFileName": "assets/js/bundle.js",
  "inputFiles": [
    "assets/js/site.js",
    "assets/js/site1.js"
  ],
  "minify": {
    "enabled": true,
    "renameLocals": true
  }
},
{
  "outputFileName": "assets/css/bundle.css",
  "inputFiles": [
    "assets/css/site.css",
    "assets/css/site1.css"
  ],
  "minify": {
    "enabled": true,
    "renameLocals": true
  }
}
]

А дальше делаем как нам требуется (читаем руководство).

Продолжаем совершенствовать наш шаблон.

При публикации убеждаемся, что всё компилируется, объединяется, минифицируется и падает в нужную папку, с нужными путями. Но! Падает всё подряд, что есть в проекте - служебные папки и файлы, файлы проекта и сборки, исходники... И даже если при публикации включена опция Delete Existing Files в папке Publish создаётся рекурсивная вложенность. А публикация подразумевает готовое приложение - только рабочие оптимизированные файлы и ничего лишнего. Займёмся тюнингом публикации. Открываем файл "App_Data\PublishProfiles\FolderProfile.pubxml". По умолчанию он выглядит примерно так:

<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
  <PropertyGroup>
    <DeleteExistingFiles>true</DeleteExistingFiles>
    <ExcludeApp_Data>true</ExcludeApp_Data>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
    <PublishProvider>FileSystem</PublishProvider>
    <PublishUrl>bin\Publish</PublishUrl>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <_TargetId>Folder</_TargetId>
    <SiteUrlToLaunchAfterPublish />
    <PrecompileBeforePublish>true</PrecompileBeforePublish>
    <EnableUpdateable>true</EnableUpdateable>
    <DebugSymbols>false</DebugSymbols>
    <WDPMergeOption>DonotMerge</WDPMergeOption>
  </PropertyGroup>
</Project>

В принципе то, что мы задали в диалоге настройки публикации. Сильно вдаваться не буду в детали, но методом «научного тыка» я пришёл к такому содержимому:

<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
  <PropertyGroup>
    <DeleteExistingFiles>true</DeleteExistingFiles>
    <ExcludeApp_Data>false</ExcludeApp_Data>
    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <LaunchSiteAfterPublish>true</LaunchSiteAfterPublish>
    <PublishProvider>FileSystem</PublishProvider>
    <PublishUrl>Publish</PublishUrl>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <_TargetId>Folder</_TargetId>
    <SiteUrlToLaunchAfterPublish />
    <!--Excluding-->
    <ExcludeFilesFromDeployment>*.config;*.json;*.sln;**\*.ts;**\*.map;assets\js\site.js;assets\js\site1.js;assets\js\bundle.js;assets\css\site.css;assets\css\site1.css;assets\css\bundle.css;_vstemplate;SimpleSite.zip;</ExcludeFilesFromDeployment>
    <ExcludeFoldersFromDeployment>packages;App_Data;Publish;</ExcludeFoldersFromDeployment>
    <PrecompileBeforePublish>true</PrecompileBeforePublish>
    <EnableUpdateable>true</EnableUpdateable>
    <DebugSymbols>false</DebugSymbols>
    <WDPMergeOption>DonotMerge</WDPMergeOption>
  </PropertyGroup>
</Project>

В принципе всё понятно из тегов и директив. Единого полного руководства не нашёл, либо не работает, либо противоречит друг другу. Кто что посоветует - буду только рад.

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

Собираем всё. Делаем экспорт шаблона. Любым способом редактируем  файл *.vstemplate, импортируем в Visual Studio и наслаждаемся СВОИМ шаблоном проекта.

А мой вариант проекта разместил здесь. Там ещё до кучи накидал всего... кому будет интересно увидит. Также смотрите комментарии в файлах.

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.