Search code examples
msbuild.net-coremsdeploy

publish core build environment control


What controls the environment passed to webpack when invoking Publish triggers a build? Look at this:

1>------ Build started: Project: MeshCut, Configuration: Debug Any CPU ------
1>MeshCut -> D:\MeshCut\bin\Debug\netcoreapp2.1\MeshCut.dll
2>------ Publish started: Project: MeshCut, Configuration: Debug Any CPU ------
MeshCut -> D:\MeshCut\bin\Debug\netcoreapp2.1\MeshCut.dll
npm install
audited 11025 packages in 7.787s
found 0 vulnerabilities

node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod
Hash: dadea967a4be0fa40482
Version: webpack 4.22.0

. . .
    Publish Succeeded.

========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
========== Publish: 1 succeeded, 0 failed, 0 skipped ==========

In the first line it is obviously a debug build but this line

node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod

is clearly passed env.prod which is making it impossible to find out why there is an error in production that doesn't occur when the server is run from the IDE.

I tried setting an environmnent variable ASPNETCORE_ENVIRONMENT to "Development" but this was not helpful, probably because this is a run-time thing.

Ultimately this is an msbuild thing. The combination of a pubxml file and the csproj file are the inputs to msbuild.

Within the csproj file env.prod is a literal. IF there were some way to make the this value depend on the build type (release/debug) the problem could be resolved.

There is another question inspired by fundamentally the same problem, but the asker is satisfied with discovering that he can control it by editing the csproj. This is not helpful for respecting release/debug.

It's an MSBUILD thing. That means look in the csproj file and sure enough we find this

<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
  <!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
    <Exec Command="npm install" />
    <Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
    <Exec Command="node node_modules/webpack/bin/webpack.js --env.prod" />

and it is easy to find the culprits in the second and third Exec statements.

The question remaining is how to either conditionally specify a parameter value, or how to conditionally specify a completely different command-line.

This Microsoft documentation appears to describe how to do the second option, but msbuild didn't like my attempt to wrap the exec elements with choose and when elements and I could still use some help.


Solution

  • It's an MSBUILD thing. That means look in the csproj file and sure enough we find this

    <Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
      <!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
        <Exec Command="npm install" />
        <Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" />
        <Exec Command="node node_modules/webpack/bin/webpack.js --env.prod" />
    

    and it is easy to find the culprit in the second of the Exec statements.

    Exec supports a Condition attribute. Fortunately elsewhere in the CSPROJ file one of the targets is already conditional on the exact condition we require. With a little copy/paste and tweaking, the code becomes...

    <Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
      <!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
      <Exec Command="npm install" />
      <Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.dev" 
            Condition=" '$(Configuration)' == 'Debug' " />
      <Exec Command="node node_modules/webpack/bin/webpack.js --env.dev" 
            Condition=" '$(Configuration)' == 'Debug' " />
    
      <Exec Command="node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js --env.prod" 
            Condition=" '$(Configuration)' == 'Release' " />
      <Exec Command="node node_modules/webpack/bin/webpack.js --env.prod" 
            Condition=" '$(Configuration)' == 'Release' " />