2017-01-23 3 views
0

Ich verwende Dotnet-Core für meine Backend-Website, MVC-Webseite (index.cshtml) und angular2 für meine Anwendung verwenden.Wie benutzt man webpack HASH Dateiname und dotnet publish?

Mein Problem ist, dass mit jeder neuen Version, Benutzer, die alten Javascript-Dateien zu erhalten, weil meine index.cshtml wie dieses ich auch

@{ 
    Layout = ""; 
} 
<!DOCTYPE html> 
<html> 
<head> 
    <base href="/"> 
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" /> 
    <link rel="shortcut icon" type="image/x-icon" href="favicon.ico" /> 
</head> 
<!-- 3. Display the application --> 
<body> 
    <my-app> 
     <div class="container text-md-center"> 
      <div class="mb-1">Loading application, please wait...</div> 
      <div> 
       <i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i> 
       <span class="sr-only">Loading...</span> 
      </div> 
     </div> 
    </my-app> 

    <script defer type="text/javascript" src="~/dist/webpack.bundle.js"></script> 
    @if (ViewBag.Environment != "Production") 
    { 
     <script defer type="text/javascript" src="~/dist/app-style.bundle.js"></script> 
     <script defer type="text/javascript" src="~/dist/vendor-style.bundle.js"></script> 
    } 

    <script defer type="text/javascript" src="~/dist/polyfills.bundle.js"></script> 
    <script defer type="text/javascript" src="~/dist/vendor.bundle.js"></script> 
    <script defer type="text/javascript" src="~/dist/builders.bundle.js"></script> 
    <script defer type="text/javascript" src="~/dist/app.bundle.js"></script> 
</body> 
</html> 

sieht webpack bin mit allen zu bündeln meine Typoskript, html Ansichten etc .

in meinem dotnet "prepublish" Tags veröffentlichen, i webpack eine Produktions Build zu erstellen, wie unten

"scripts": { 
    "prepublish": [ "npm run build" ], 
} 

Und in meinem package.json fil zu laufen bin immer e, "npm run build" ist so definiert.

"scripts": { 
    "clean": "rimraf node_modules doc dist && npm cache clean", 
    "clean-install": "npm run clean && npm install", 
    "clean-start": "npm run clean-install && npm start", 
    "watch": "webpack --watch --progress --profile", 
    "debug": "rimraf dist && webpack --progress --profile --bail", 
    "build": "rimraf dist && webpack --progress --profile --bail", 
    "lint": "tslint --force \"wwwroot/app/**/*.ts\"", 
    "docs": "typedoc --options typedoc.json wwwroot/app/app.component.ts", 
    "postinstall": "npm run" 
}, 

Das alles sehr gut ist, aber da Dotnet an einen neuen Speicherort kopiert die Dateien veröffentlichen und webpack läuft vor der Kopie ... Wie kann ich meine index.cshtml Datei aktualisieren, um die Hash-Tags für Skript zu schließen Dateien, ohne die tatsächliche index.cshtml Datei zu ändern, weil das natürlich eingecheckt ist und nicht eine neue Version veröffentlichen will, sobald ich veröffentliche (wie es sollte mehr eine Vorlage sein)

Jede Hilfe sehr geschätzt!

EDIT Hier ist meine eigentliche webpack.config.js

Datei
var path = require('path'); 
var webpack = require('webpack'); 
var autoprefixer = require('autoprefixer'); 
var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin; 
var ExtractTextPlugin = require('extract-text-webpack-plugin'); 
var ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin; 

/** 
* Env 
* Get npm lifecycle event to identify the environment 
*/ 
var ENV = process.env.npm_lifecycle_event; 
var isTestWatch = ENV === 'test-watch'; 
var isTest = ENV === 'test' || isTestWatch; 
var isProd = ENV === 'build'; 

console.log(isProd ? 'Production build...' : 'Debug build...'); 

// Webpack Config 
module.exports = function makeWebpackConfig() { 

    /** 
    * Config 
    * Reference: http://webpack.github.io/docs/configuration.html 
    * This is the object where all configuration gets set 
    */ 
    var config = {}; 

    /** 
    * Devtool 
    * Reference: http://webpack.github.io/docs/configuration.html#devtool 
    * Type of sourcemap to use per build type 
    */ 
    if (isProd) { 
     config.devtool = 'source-map'; 
    } 
    else if (isTest) { 
     config.devtool = 'inline-source-map'; 
    } 
    else { 
     config.devtool = 'source-map'; 
    } 

    /** 
    * Entry 
    * Reference: http://webpack.github.io/docs/configuration.html#entry 
    */ 
    config.entry = isTest ? {} : { 
     'polyfills':  './wwwroot/polyfills.ts', 
     'vendor':   './wwwroot/vendor.ts', 
     'builders':  './wwwroot/builders.ts', 
     'app':    './wwwroot/app.ts', 
     'vendor-style': './wwwroot/style/vendor-style.ts', 
     'app-style':  './wwwroot/style/app-style.ts' 
    }; 

    /** 
    * Output 
    * Reference: http://webpack.github.io/docs/configuration.html#output 
    */ 
    config.output = isTest ? {} : { 
     path: './wwwroot/dist', 
     publicPath: './dist/', 
     filename: '[name].bundle.js', 
     sourceMapFilename: '[name].bundle.js.map', 
     chunkFilename: '[id].chunk.js' 
    }; 

    /** 
    * Resolve 
    * Reference: http://webpack.github.io/docs/configuration.html#resolve 
    */ 
    config.resolve = { 
     // only discover files that have those extensions 
     extensions: ['.ts', '.js'] 
    }; 

    var atlOptions = ''; 
    if (isTest && !isTestWatch) { 
     // awesome-typescript-loader needs to output inlineSourceMap for code coverage to work with source maps. 
     atlOptions = 'inlineSourceMap=true&sourceMap=false'; 
    } 

    /** 
    * Loaders 
    * Reference: http://webpack.github.io/docs/configuration.html#module-loaders 
    * List: http://webpack.github.io/docs/list-of-loaders.html 
    * This handles most of the magic responsible for converting modules 
    */ 
    config.module = { 
     rules: [ 
      // .ts files for TypeScript 
      { 
       test: /\.ts$/, 
       loader: 'awesome-typescript-loader?' + atlOptions, 
       exclude: [isTest ? /\.(e2e)\.ts$/ : /\.(spec|e2e)\.ts$/, /node_modules\/(?!(ng2-.+))/] 
      }, 
      { 
       test: /\.html$/, 
       loader: 'html-loader' 
      }, 
      { 
       test: /\.css$/, 
       loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: ['css-loader', 'postcss-loader'] }) 
      }, 
      { 
       test: /\.scss$/, 
       loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: ['css-loader', 'postcss-loader', 'sass-loader'] }) 
      }, 
      { 
       test: /\.(jpe?g|png|gif|svg)$/i, 
       use: [ 
        { 
         loader: 'file-loader', 
         options: { 
          hash: 'sha512', 
          digest: 'hex', 
          name: '[hash].[ext]' 
         } 
        }, 
        { 
         loader: 'image-webpack-loader', 
         options: { 
          bypassOnDebug: true, 
          optimizationLevel: 7, 
          interlaced: false 
         } 
        } 
       ] 
      }, 
      { 
       test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, 
       loader: 'file-loader' 
      }, 
      { 
       test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, 
       use: [ 
        { 
         loader: 'url-loader', 
         options: { 
          prefix: 'font/', 
          limit: 5000, 
          publicPath: '../dist/' 
         } 
        } 
       ] 
      }, 
      { 
       test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, 
       use: [ 
        { 
         loader: 'url-loader', 
         options: { 
          limit: 10000, 
          mimetype: 'application/octet-stream', 
          publicPath: '../dist/' 
         } 
        } 
       ] 
      }, 
      { 
       test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, 
       use: [ 
        { 
         loader: 'url-loader', 
         options: { 
          limit: 10000, 
          mimetype: 'image/svg+xml' 
         } 
        } 
       ] 
      } 
     ] 
    }; 

    if (!isTest || !isTestWatch) { 
     // tslint support 
     config.module.rules.push({ 
      test: /\.ts$/, 
      enforce: 'pre', 
      loader: 'tslint-loader' 
     }); 
    } 

    /** 
    * Plugins 
    * Reference: http://webpack.github.io/docs/configuration.html#plugins 
    * List: http://webpack.github.io/docs/list-of-plugins.html 
    */ 
    config.plugins = [ 

     // Define env variables to help with builds 
     // Reference: https://webpack.github.io/docs/list-of-plugins.html#defineplugin 
     new webpack.DefinePlugin({ 
      // Environment helpers 
      'process.env': { 
       ENV: JSON.stringify(ENV) 
      } 
     }), 

     new webpack.LoaderOptionsPlugin({ 
      minimize: true, 
      debug: true, 
      options: { 
       /** 
       * Apply the tslint loader as pre/postLoader 
       * Reference: https://github.com/wbuchwalter/tslint-loader 
       */ 
       tslint: { 
        emitErrors: false, 
        failOnHint: false 
       }, 

       // htmlLoader 
       htmlLoader: { 
        minimize: true, 
        removeAttributeQuotes: false, 
        caseSensitive: true, 
        customAttrSurround: [ [/#/, /(?:)/], [/\*/, /(?:)/], [/\[?\(?/, /(?:)/] ], 
        customAttrAssign: [ /\)?\]?=/ ] 
       }, 

       // postcss 
       postcss: [ 
        autoprefixer({ 
         browsers: ['last 2 version'] 
        }) 
       ] 
      } 
     }) 
    ]; 

    if (!isTest && !isTestWatch) { 
     config.plugins.push(
      new ForkCheckerPlugin(), 

      // Generate common chunks if necessary 
      // Reference: https://webpack.github.io/docs/code-splitting.html 
      // Reference: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin 
      new CommonsChunkPlugin({ 
       name: ['app', 'builders', 'vendor', 'polyfills', 'webpack'], 
       minChunks: Infinity 
      }), 

      // Extract css files 
      // Reference: https://github.com/webpack/extract-text-webpack-plugin 
      // Disabled when in test mode or not in build mode 
      new ExtractTextPlugin({ 
       filename: '[name].css', 
       disable: !isProd 
      }) 
     ); 
    } 

    // Add build specific plugins 
    if (isProd) { 
     config.plugins.push(
      // Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin 
      // Only emit files when there are no errors 
      new webpack.NoErrorsPlugin(), 

      // // Reference: http://webpack.github.io/docs/list-of-plugins.html#dedupeplugin 
      // // Dedupe modules in the output 
      // new webpack.optimize.DedupePlugin(), 

      // Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin 
      // Minify all javascript, switch loaders to minimizing mode 
      new webpack.optimize.UglifyJsPlugin({ 
       sourceMap: true, 
       mangle: { 
        keep_fnames: true 
       } 
      }) 
     ); 
    } 

    return config; 
}(); 
+0

vielleicht hilft diese http://michaco.net/blog/Angular4GettingHashedWebpackBundlesWorkingInASPNETCoreMVC – MichaC

Antwort

0

Dies kann

output: { 
    path: path.resolve(__dirname, './your-output-dir'), 
    publicPath: '/your-output-dir/', 
    filename: '[name][hash].js' 
}, 

daher in Ihrem webpack Config konfiguriert werden, wird es

sein
/dist/appasdadfasd.js //something like that 

Sie werden nicht die Caching-Iss haben es.

<script defer type="text/javascript" src="~/dist/app.bundle.js"></script> 

Ihre app.bundle.js auf diese Datei /dist/appasdadfasd.js

+0

Aber wird nicht die app.bundle.js Datei zwischengespeichert werden, und versuchen somit eine falsche Datei zu laden ?? Kann ich dieses Script-Tag nicht direkt auf der index.cshtml-Seite erzwingen? – Gillardo

+0

Nein, es wird nicht die falsche Datei geladen. Ich benutze das, ich habe keine Probleme damit! Keine Notwendigkeit, es das HTML-Tag erzwingen, Webpack kümmert sich bereits darum. – highFlyingDodo

+0

Ich denke, ich muss etwas vermissen, wie ich Ihre Änderungen versuchte, und es würde meine Datei überhaupt nicht laden. Ich habe meine Datei webpack.config.js angehängt, wenn Sie einen Blick darauf werfen und genau sehen können, was ich ändern muss. – Gillardo

0

Warnung: Ich verwende diese nicht nähere mich mir. Ich habe es ausprobiert, aber das Problem mit mehreren übereinstimmenden Dateien war ein Problem. Lassen Sie die Antwort für den Fall, dass es jemand in einer anderen Situation hilft.

Ein anderer Weg, dies zu tun ist:

  • konfigurieren webpack mit [name] [chunkhash] Js und [Name] [chunkhash] .css, die reguläre Ausdrücke weniger wahrscheinlich zu machen
  • stottern..
  • Code schreiben, um Bundle zu ergänzen.Include das ist flexibler, zB Unterstützung {Hash} zusätzlich zu {Version} und *, wahrscheinlich mit regulären Ausdrücken
  • Stellen Sie sicher, dass, wenn mehrere Dateien mit Ihrem regulären Ausdruck entsprechen, Sie nehmen der Letzte!
  • Richten Sie Ihre Dateien in BundleConfig als Bundles ein.cs
  • auf .cshtml Seiten verwenden Scripts.Render und Styles.Render in den richtigen zugrunde liegenden Dateien für jedes Bündel

Hier ziehen einige Beispiel-Code, der die passenden physischen Dateien trotz des Hash-Namen findet. Ich werde es in BundleConfig.cs als Übung für den Leser integrieren, da es je nachdem, was Sie sonst noch machen, anders sein kann. Es muss auch geändert werden, um nur die neueste Datei zu erhalten.

private static string ReplaceHash(string pathWithHash) 
    { 
     var i = pathWithHash.LastIndexOf('/'); 
     var virtualPath = pathWithHash.Substring(0, i); 
     var physicalPath = HostingEnvironment.MapPath(virtualPath); 
     var fileName = pathWithHash.Substring(i + 1); 

     if (!Directory.Exists(physicalPath)) 
     { 
      throw new FfcException(string.Format("Bundle path '{0}' not found", pathWithHash)); 
     } 
     var re = new Regex(fileName 
      .Replace(".", @"\.") 
      .Replace("{hash}", @"([0-9a-fA-F]+)") 
      .Replace("{version}", @"(\d+(?:\.\d+){1,3})") 
      .Replace("*", @".*") 
      , RegexOptions.IgnoreCase 
     ); 

     fileName = fileName 
      .Replace("{hash}", "*") 
      .Replace("{version}", "*"); 

     var matchingFiles = Directory.EnumerateFiles(physicalPath, fileName).Where(file => re.IsMatch(file)).ToList(); 
     if (matchingFiles.Count == 0) 
     { 
      throw new FfcException(string.Format("Bundle resource '{0}' not found", pathWithHash)); 
     } 
     if (matchingFiles.Count > 1) 
     { 
      // TODO: need to pick the most recently created matching file 
      throw new FfcException(string.Format("Ambiguous Bundle resource '{0}' requested", pathWithHash)); 
     } 
     var matchingPhysicalFile = matchingFiles[0]; 
     var matchingVirtualFile = matchingPhysicalFile.Replace(physicalPath + "\\", virtualPath + "/"); 
     return matchingVirtualFile; 
    } 
Verwandte Themen