Buda Gavril
Buda Gavril

Reputation: 21647

Setup a web project with elm in visual studio 2015

How to setup a web project with elm in visual studio 2015?

We started a new project and we need it in visual studio for the continuous integration and build deploy to a certain server.

My issue is that I didn't found a elm project template and I've only heard about elm these days, so it's something new for me also.

Any help would be appreciated.

Upvotes: 2

Views: 826

Answers (2)

Gabor
Gabor

Reputation: 1676

We came up with a structure where our UI is a separate project and completely written in Elm while the backend is in ASP.NET. The whole thing is in one Visual Studio solution and can be compiled using VS2015 or MSBuild in TeamCity.

We use VS Code for developing the UI though. I do not know of any Visual Studio support for Elm.

This is the project file (YourUI.csproj) that is included in the UI project:

<?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>

As you can see, in the background we use npm and gulp to do the actual work. The important pieces from our gulp file (including the Elm CSS generation and WebPack bundling):

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');
});

The ASP.NET project file contains the following BeforeBuild instructions:

  <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>

Upvotes: 2

Chad Gilbert
Chad Gilbert

Reputation: 36375

It doesn't technically need to be in Visual Studio 2015 to be part of continuous integration or development. For editing, you'll probably have less friction using Visual Studio Code (or other editors like Sublime, Vim, Atom, etc).

However, if you still want it tied into the Visual Studio 2015 ecosystem, you're going to want to use Task Runner integration. You already have grunt and gulp task runners built into the IDE. You could create a gulp task and use gulp-elm to automatically watch and compile your Elm code.

Personally, I'm a fan of Webpack for Elm development. With an additional Visual Studio 2015 plugin for Webpack task runners, you should be able to tie it together nicely. (caveat: I haven't personally tried that combination but it looks legitimate)

Upvotes: 1

Related Questions