2017-04-19 112 views
2

我的webpack配置有問題。在實現html-webpack-plugin後,我得到一個錯誤,從生成的index.html有整個錯誤堆棧。Webpack,html-webpack-plugin,錯誤:兒童編譯失敗

錯誤堆棧: 的Html的WebPack插件:

 
    Error: Child compilation failed: 
    Conflict: Multiple assets emit to the same filename index.html: 
    Error: Conflict: Multiple assets emit to the same filename index.html

  • compiler.js:76 [Pre-build]/[html-webpack-plugin]/lib/compiler.js:76:16

  • Compiler.js:291 Compiler. [Pre-build]/[webpack]/lib/Compiler.js:291:10

  • Compiler.js:494 [Pre-build]/[webpack]/lib/Compiler.js:494:13

  • Tapable.js:138 next [Pre-build]/[tapable]/lib/Tapable.js:138:11

  • CachePlugin.js:62 Compiler. [Pre-build]/[webpack]/lib/CachePlugin.js:62:5

  • Tapable.js:142 Compiler.applyPluginsAsyncSeries [Pre-build]/[tapable]/lib/Tapable.js:142:13

  • Compiler.js:491 [Pre-build]/[webpack]/lib/Compiler.js:491:10

  • Tapable.js:131 Compilation.applyPluginsAsyncSeries [Pre-build]/[tapable]/lib/Tapable.js:131:46

  • Compilation.js:645 self.applyPluginsAsync.err [Pre-build]/[webpack]/lib/Compilation.js:645:19

  • Tapable.js:131 Compilation.applyPluginsAsyncSeries [Pre-build]/[tapable]/lib/Tapable.js:131:46

  • Compilation.js:636 self.applyPluginsAsync.err [Pre-build]/[webpack]/lib/Compilation.js:636:11

  • Tapable.js:131 Compilation.applyPluginsAsyncSeries [Pre-build]/[tapable]/lib/Tapable.js:131:46

  • Compilation.js:631 self.applyPluginsAsync.err [Pre-build]/[webpack]/lib/Compilation.js:631:10

  • Tapable.js:131 Compilation.applyPluginsAsyncSeries [Pre-build]/[tapable]/lib/Tapable.js:131:46

  • Compilation.js:627 sealPart2 [Pre-build]/[webpack]/lib/Compilation.js:627:9

  • Tapable.js:131 Compilation.applyPluginsAsyncSeries [Pre-build]/[tapable]/lib/Tapable.js:131:46

  • Compilation.js:575 Compilation.seal [Pre-build]/[webpack]/lib/Compilation.js:575:8

  • Compiler.js:488 [Pre-build]/[webpack]/lib/Compiler.js:488:16

  • Tapable.js:225 [Pre-build]/[tapable]/lib/Tapable.js:225:11

  • Compilation.js:477 _addModuleChain [Pre-build]/[webpack]/lib/Compilation.js:477:11

  • Compilation.js:448 processModuleDependencies.err [Pre-build]/[webpack]/lib/Compilation.js:448:13

  • next_tick.js:73 _combinedTickCallback internal/process/next_tick.js:73:7

  • next_tick.js:104 process._tickCallback internal/process/next_tick.js:104:9

我的WebPack配置代碼:

var webpack = require('webpack'), 
    path = require('path'); 


var CopyWebpackPlugin = require('copy-webpack-plugin'), 
    ExtractTextWebpackPlugin = require('extract-text-webpack-plugin'), 
    HtmlWebpackPlugin = require('html-webpack-plugin'), 

const sourcePath = path.resolve(__dirname, './src'); 
const staticPath = path.resolve(__dirname, './static'); 

module.exports = function (env) { 

    const nodeEnv = env && env.prod ? 'production' : 'development'; 
    const isProd = nodeEnv === 'production'; 

    const postcssLoader = { 
     loader: 'postcss-loader', 
     options: { 
      plugins: function() { 
       return [ 
        require('autoprefixer') 
       ]; 
      } 
     } 
    } 

    const plugins = [ 
     new webpack.optimize.CommonsChunkPlugin({ 
      name: 'vendor', 
      minChunks: Infinity, 
      filename: 'vendor.bundle.js' 
     }), 
     new webpack.EnvironmentPlugin({ 
      NODE_ENV: nodeEnv, 
     }), 
     new HtmlWebpackPlugin({ 
      template: 'index.html', 
      minify: { 
       removeComments: true, 
       collapseWhitespace: true, 
       removeAttributeQuotes: true 
      }, 
      chunksSortMode: 'dependency' 
     }) 
    ]; 

    if(isProd) { 
     plugins.push(
      new webpack.LoaderOptionsPlugin({ 
       minimize: true, 
       debug: false 
      }), 
      new webpack.optimize.UglifyJsPlugin({ 
       compress: { 
        warnings: false, 
        screw_ie8: true, 
        conditionals: true, 
        unused: true, 
        comparisons: true, 
        sequences: true, 
        dead_code: true, 
        evaluate: true, 
        if_return: true, 
        join_vars: true, 
       }, 
       output: { 
        comments: false, 
       }, 
      }) 
     ); 
    } else { 
     plugins.push(
      new webpack.HotModuleReplacementPlugin() 
     ); 
    } 

    return { 
     devtool: isProd? 'source-map' : 'eval', 
     context: sourcePath, 

     entry: { 
      app: './app/entry.ts', 
      vendor: './app/vendor.ts' 
     }, 

     output: { 
      path: staticPath, 
      filename: '[name].bundle.js', 
     }, 

     module: { 
      rules: [ 
       { 
        test: /\.html$/, 
        exclude: /node_modules/, 
        use: { 
         loader: 'file-loader', 
         query: { 
          name: '[name].[ext]' 
         }, 
        }, 
       }, 
       { 
        test: /\.css$/, 
        exclude: /node_modules/, 
        use: [ 
         'style-loader', 
         'css-loader', 
         'postcss-loader' 
        ] 
       }, 
       { 
        test: /\.scss$/, 
        exclude: /node_modules/, 
        use: [ 
         'style-loader', 
         'css-loader', 
         'postcss-loader', 
         'sass-loader' 
        ] 
       }, 
       { 
        test: /\.ts$/, 
        exclude: /node_modules/, 
        use: [ 
         'ts-loader' 
        ], 
       }, 
      ], 
     }, 

     resolve: { 
      alias: { 
       Public: path.resolve(__dirname,'src/public'), 
       Style: path.resolve(__dirname,'src/styles') 
      }, 
      extensions: ['.ts','.js', '.html'], 
      modules: [ 
       path.resolve(__dirname, 'node_modules'), 
       sourcePath 
      ] 
     }, 

     plugins, 

     performance: isProd && { 
      maxAssetSize: 100, 
      maxEntrypointSize: 300, 
      hints: 'warning' 
     }, 

     stats: { 
      colors: { 
       green: '\u001b[32m' 
      } 
     }, 

     devServer: { 
      contentBase: './src', 
      historyApiFallback: true, 
      port: 3000, 
      compress: isProd, 
      inline: !isProd, 
      hot: !isProd, 
      stats: { 
       assets: true, 
       children: false, 
       chunks: false, 
       hash: false, 
       modules: false, 
       publicPath: false, 
       timings: true, 
       version: false, 
       warnings: true, 
       color: { 
        green: '\u001b[32m' 
       } 
      }, 
     } 
    }; 
}; 

我無法找到任何錯誤來源,也許我有點累了,但我想完成它,所以我希望你的幫助球員。

也許我應該使用一些raw-loader加載.html(?),這並不會讓我開心。

回答

4

問題確實是file-loader,因爲它只是將文件複製過來。在html-webpack-plugin嘗試寫入index.html時,它已被寫入file-loader,因此導致衝突。

根據您的需求,有幾種方法可以解決該問題。

對於HTML,您可以使用html-loader,但如果您希望簡單地複製導入的HTML,則不是正確的選擇。要清楚,通過導入的HTML我並不是指html-webpack-plugin使用的模板。

如果您想繼續使用file-loader作爲其他HTML文件,則可以排除index.html,以便html-webpack-plugin可以回退到其默認加載程序。 require.resolve的工作方式與require類似,但會爲您提供模塊的完整路徑而不是其內容。

{ 
    test: /\.html$/, 
    exclude: [/node_modules/, require.resolve('./index.html')], 
    use: { 
     loader: 'file-loader', 
     query: { 
      name: '[name].[ext]' 
     }, 
    }, 
}, 

當沒有裝載模板匹配,html-webpack-plugin使用一個ejs loader as a fallback。如果您不需要用於.html文件的任何加載程序,則可以完全刪除該規則並且它可以正常工作。這是不太可能的,否則您首先不會有.html規則,但這也意味着您可以使用.ejs擴展名來不應用.html規則,因爲所有HTML都是有效的EJS。你會重命名index.htmlindex.ejs,並相應地改變你的插件配置:

new HtmlWebpackPlugin({ 
    template: 'index.ejs', 
    minify: { 
     removeComments: true, 
     collapseWhitespace: true, 
     removeAttributeQuotes: true 
    }, 
    chunksSortMode: 'dependency' 
}) 
+0

大答案和解釋!我非常感謝你的文章,並且我決定留在'html-webpack-plugin'中,並且刪除'html-loader',只要我做單點。真正的感謝,現在對我來說事情更加清晰。 =) –