在 visual studio 2015 年使用 elm 设置一个 web 项目

Setup a web project with elm in visual studio 2015

如何在 visual studio 2015 中使用 elm 设置 Web 项目?

我们开始了一个新项目,我们需要在 visual studio 中进行持续集成和构建部署到某个服务器。

我的问题是我没有找到 elm 项目模板,我最近才听说过 elm,所以它对我来说也是新事物。

如有任何帮助,我们将不胜感激。

技术上不需要在 Visual Studio 2015 年成为持续集成或开发的一部分。对于编辑,使用 Visual Studio 代码(或其他编辑器,如 Sublime、Vim、Atom 等)可能会减少摩擦。

但是,如果您仍希望它与 Visual Studio 2015 生态系统相关联,您将需要使用 Task Runner 集成。您已经 grunt and gulp task runners built into the IDE. You could create a gulp task and use gulp-elm 可以自动监视和编译您的 Elm 代码。

就个人而言,我是用于 Elm 开发的 Webpack 的粉丝。加上额外的 Visual Studio 2015 plugin for Webpack task runners,您应该能够很好地将它们组合在一起。 (警告:我没有亲自尝试过这种组合,但它看起来是合法的)

我们想出了一个结构,其中 UI 是一个单独的项目,完全用 Elm 编写,而后端在 ASP.NET 中。 整个事情都在一个 Visual Studio 解决方案中,可以在 TeamCity 中使用 VS2015 或 MSBuild 进行编译。

虽然我们使用 VS Code 来开发 UI。我不知道有任何 Visual Studio 对 Elm 的支持。

这是包含在 UI 项目中的项目文件 (YourUI.csproj):

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <ProjectGuid>{B9D43DC2-6337-4605-BBE2-7C7C765EDC20}</ProjectGuid>
    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <BuildTask>build:dev</BuildTask>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <BuildTask>build:release</BuildTask>
  </PropertyGroup>
  <Target Name="Build">
    <Exec Command="echo Executing npm install..." Condition="!Exists('$(ProjectDir)node_modules')" />
    <Exec Command="npm install" Condition="!Exists('$(ProjectDir)node_modules')" />     
    <Exec Command="echo Building the UI using GULP..." />
    <Exec Command="echo ---------------------------------------------" />
    <Exec Command="gulp $(BuildTask)" />
    <Exec Command="echo ---------------------------------------------" />
  </Target>
  <Target Name="Clean">
    <Exec Command="gulp clean:all" />
  </Target>
  <Target Name="Rebuild" DependsOnTargets="Clean;Build" />
  <ItemGroup>
    <None Include="readme.md" />
  </ItemGroup>
</Project>

如您所见,在后台我们使用 npmgulp 来完成实际工作。 我们 gulp 文件中的重要部分(包括 Elm CSS 生成和 WebPack 捆绑):

gulp.task('elm-init', function (cb) {
    return gulp.src('src/*.elm')
        .pipe(elm())
        .pipe(gulp.dest('JS/generated'));
});

gulp.task('elm:dev', ['elm-init'], function (cb) {
    return gulp.src('src/main.elm')
        .pipe(elm.bundle('elm.js'), {
            debug: true
        })
        .pipe(gulp.dest('JS/generated'));
});
gulp.task('elm:release', ['elm-init'], function (cb) {
    return gulp.src('src/main.elm')
        .pipe(elm.bundle('elm.js'))
        .pipe(gulp.dest('JS/generated'));
});

bundle = function () {
    return gulp.src('JS/index.js')
        .pipe(webpackGulp({
            output: {
                filename: 'Ui.js',
            }
        }))
        .pipe(gulp.dest('build/'));
}
gulp.task('bundle:dev', [/*project spcific things, */ 'elm:dev'], bundle);
gulp.task('bundle:release', [/*project spcific things, */ 'elm:release'], bundle);

gulp.task('css', function (cb) {
    mkdirp('build/css', function (err) {
        if (err) console.error(err)
    });

    exec(path.resolve('./node_modules/.bin/elm-css')
        + ' --pathToMake ./node_modules/.bin/elm-make'
        + ' src/Stylesheets.elm',
        function (err, stdout, stderr) {
            console.log(stdout);
            console.log(stderr);
            cb(err);
        });
});

gulp.task('build:dev', function (cb) {
    runSequence('clean:dev', 'bundle:dev', 'css');
});

ASP.NET 项目文件包含以下 BeforeBuild 说明:

  <Target Name="BeforeBuild">
    <MSBuild 
        Projects="..\YourUI\YourUI.csproj"
        Condition="'$(Configuration)'=='Release' OR !(Exists('$(SolutionDir)YourUI\build\Ui.js') AND Exists('$(SolutionDir)YourUI\build\css'))" 
        Targets="Build" />
    <Exec Command="echo Creating UI resources for $(Configuration)..." />
    <!-- Delete old links -->
    <Delete Files="$(ProjectDir)Scripts\Ui.js" />
    <Delete Files="$(ProjectDir)Scripts\Ui.min.js" />
    <RemoveDir Directories="$(ProjectDir)Content\Ui" />
    <!---->
    <!---->
    <!-- DEBUG build-->
    <!---->
    <Exec Condition=" '$(Configuration)'=='Debug' " Command="mklink $(ProjectDir)Scripts\Ui.js $(SolutionDir)YourUI\build\Ui.js" />
    <Exec Condition=" '$(Configuration)'=='Debug' " Command="mklink /d $(ProjectDir)Content\Ui $(SolutionDir)YourUI\build\css" />
    <!---->
    <!---->
    <!-- RELEASE build-->
    <!---->
    <ItemGroup Condition=" '$(Configuration)'!='Debug' ">
      <ElmApp Include="$(SolutionDir)YourUI\build\Ui.min.js" />
      <ElmStyles Include="$(SolutionDir)YourUI\build\css\*.css" />
    </ItemGroup>
    <Copy Condition=" '$(Configuration)'!='Debug' " SourceFiles="@(ElmApp)" DestinationFolder="$(ProjectDir)Scripts" />
    <Copy Condition=" '$(Configuration)'!='Debug' " SourceFiles="@(ElmStyles)" DestinationFolder="$(ProjectDir)Content\Ui" />
  </Target>
  <!-- Include the new files as content -->
  <ItemGroup Condition=" '$(Configuration)'=='Debug' ">
    <Content Include="Scripts\Ui.js" />
    <Content Include="Content\Ui\*.css" />
  </ItemGroup>
  <ItemGroup Condition=" '$(Configuration)'!='Debug' ">
    <Content Include="Scripts\Ui.min.js" />
    <Content Include="Content\Ui\*.css" />
  </ItemGroup>