2016-08-22 8 views
0

我有一个问题,我的webpack.prod.config正确地建立我的资产或可能是我的JS巴贝尔配置的问题。与Webpack,React,postCSS和可能的其他JS代码正在注入适当生产问题

我可以让它与开发版本一起工作,它将我的CSS内联,但当我尝试将它合并为一个CSS文件进行生产时,它不工作。无论发生什么,它都可以在Dev中工作,通过在每个相应组件中导入'./filename.css'直接注入CSS。它也可能是JS,但无论哪种方式,当我构建产品时,CSS不能正常工作,也不是JS。所有React JS组件和其他JS都不显示,只是CDN导入的静态HTML和CSS样式。当我点击由Webpack注入的脚本标记中的URL时,他们只是将我引向相同的页面,而不是我觉得奇怪的JS或CSS源代码。在构建>静态> JS + CSS输出中,JS和CSS看起来是正确的。有时我在控制台中看到其他消息时收到了一个text/html MIME。

无论是那个还是我的JS坏掉了,都没有正确的建立页面。不在我的生产版本中(与Heroku部署时相同)。我从一个create-react-app(弹出)开始,添加了Express,preCSS(用于像预处理一样的SASS),react-bootstrap和其他一些东西。

这个项目有点乱,因为它是我用来作为一个新的web开发的学习工具,从使用静态HTML + CSS转换到使用React,JS和Bootstrap(jQuery暂时在那里,因为我们将东西一起转换成纯React)。它以前没有问题,但由于我开始混淆使用postCSS + preCSS,但它不再有效。

以下是我正在使用的一些主要软件包/库。 - jQuery的(CDN的脚本标记) - BS3(CDN的脚本标记,.js文件,名为.css) - 阵营,引导 - 阵营叠加层 - 巴贝尔 - postCSS - preCSS - ExtractTextPlugin

谢谢提前寻求你的帮助。

HTML +的错误我得到的控制台

[![HTML生成] [1] [1] [![控制台错误] [2] [2]

Webpack.config.prod.js

var path = require('path'); 
var precss = require('precss'); 
var autoprefixer = require('autoprefixer'); 
var webpack = require('webpack'); 
var HtmlWebpackPlugin = require('html-webpack-plugin'); 
var ExtractTextPlugin = require('extract-text-webpack-plugin'); 
var url = require('url'); 
var paths = require('./paths'); 

var homepagePath = require(paths.appPackageJson).homepage; 
var publicPath = homepagePath ? url.parse(homepagePath).pathname : '/'; 
if (!publicPath.endsWith('/')) { 
    // Prevents incorrect paths in file-loader 
    publicPath += '/'; 
} 

module.exports = { 
    bail: true, 
    devtool: 'source-map', 
    entry: [ 
    require.resolve('./polyfills'), 
    path.join(paths.appSrc, 'index') 
    ], 
    output: { 
    path: paths.appBuild, 
    filename: 'static/js/[name].[chunkhash:8].js', 
    chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js', 
    publicPath: publicPath 
    }, 
    resolve: { 
    extensions: ['', '.js', '.json'] 
    }, 
    resolveLoader: { 
    root: paths.ownNodeModules, 
    moduleTemplates: ['*-loader'] 
    }, 
    module: { 
    preLoaders: [ 
     { 
     test: /\.js$/, 
     loader: 'eslint', 
     include: paths.appSrc 
     } 
    ], 
    loaders: [ 
     { 
     test: /\.js$/, 
     include: paths.appSrc, 
     loader: 'babel', 
     query: require('./babel.prod') 
     }, 
     { 
     test: /\.css$/, 
     include: [paths.appSrc, paths.appNodeModules], 
     // Disable autoprefixer in css-loader itself: 
     // https://github.com/webpack/css-loader/issues/281 
     // We already have it thanks to postcss. 
     loader: ExtractTextPlugin.extract('style', 'css?-autoprefixer!postcss!sass') 
     }, 
     { 
     test: /\.json$/, 
     include: [paths.appSrc, paths.appNodeModules], 
     loader: 'json' 
     }, 
     { 
     test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/, 
     include: [paths.appSrc, paths.appNodeModules], 
     loader: 'file', 
     query: { 
      // name: 'static/media/[name].[hash:8].[ext]' 
      name: 'static/media/[name].[ext]' 
     } 
     }, 
     { 
     test: /\.(mp4|webm)(\?.*)?$/, 
     include: [paths.appSrc, paths.appNodeModules], 
     loader: 'url', 
     query: { 
      limit: 10000, 
      name: 'static/media/[name].[hash:8].[ext]' 
     } 
     } 
    ] 
    }, 
    eslint: { 
    // TODO: consider separate config for production, 
    // e.g. to enable no-console and no-debugger only in prod. 
    configFile: path.join(__dirname, 'eslint.js'), 
    useEslintrc: false 
    }, 
    postcss: function() { 
    return [precss, autoprefixer]; 
    }, 
    plugins: [ 
    new HtmlWebpackPlugin({ 
     inject: true, 
     template: paths.appHtml, 
     favicon: paths.appFavicon, 
     minify: { 
     removeComments: true, 
     collapseWhitespace: true, 
     removeRedundantAttributes: true, 
     useShortDoctype: true, 
     removeEmptyAttributes: true, 
     removeStyleLinkTypeAttributes: true, 
     keepClosingSlash: true, 
     minifyJS: true, 
     minifyCSS: true, 
     minifyURLs: true 
     } 
    }), 
    new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }), 
    new webpack.optimize.OccurrenceOrderPlugin(), 
    new webpack.optimize.DedupePlugin(), 
    new webpack.optimize.UglifyJsPlugin({ 
     compress: { 
     screw_ie8: true, 
     warnings: false 
     }, 
     mangle: { 
     screw_ie8: true 
     }, 
     output: { 
     comments: false, 
     screw_ie8: true 
     } 
    }), 
    new ExtractTextPlugin('static/css/[name].[contenthash:8].css') 
    ] 
}; 

Build.js

process.env.NODE_ENV = 'production'; 
var chalk = require('chalk'); 
var fs = require('fs'); 
var path = require('path'); 
var filesize = require('filesize'); 
var gzipSize = require('gzip-size').sync; 
var rimrafSync = require('rimraf').sync; 
var webpack = require('webpack'); 
var config = require('../config/webpack.config.prod'); 
var paths = require('../config/paths'); 
var express = require('express'); 

var app = express(); 

// Remove all content but keep the directory so that 
// if you're in it, you don't end up in Trash 
rimrafSync(paths.appBuild + '/*'); 

console.log('Creating an optimized production build...'); 
webpack(config).run(function(err, stats) { 
    if (err) { 
    console.error('Failed to create a production build. Reason:'); 
    console.error(err.message || err); 
    process.exit(1); 
    } 

    console.log(chalk.green('Compiled successfully.')); 
    console.log(); 

    console.log('File sizes after gzip:'); 
    console.log(); 
    var assets = stats.toJson().assets 
    .filter(asset => /\.(js|css)$/.test(asset.name)) 
    .map(asset => { 
     var fileContents = fs.readFileSync(paths.appBuild + '/' + asset.name); 
     var size = gzipSize(fileContents); 
     return { 
     folder: path.join('build', path.dirname(asset.name)), 
     name: path.basename(asset.name), 
     size: size, 
     sizeLabel: filesize(size) 
     }; 
    }); 
    assets.sort((a, b) => b.size - a.size); 

    var longestSizeLabelLength = Math.max.apply(null, 
    assets.map(a => a.sizeLabel.length) 
); 
    assets.forEach(asset => { 
    var sizeLabel = asset.sizeLabel; 
    if (sizeLabel.length < longestSizeLabelLength) { 
     var rightPadding = ' '.repeat(longestSizeLabelLength - sizeLabel.length); 
     sizeLabel += rightPadding; 
    } 
    console.log(
     ' ' + chalk.green(sizeLabel) + 
     ' ' + chalk.dim(asset.folder + path.sep) + chalk.cyan(asset.name) 
    ); 
    }); 
    console.log(); 

    if (process.env.NODE_ENV === 'production') { 
     // Serve the static HTML file from paths.appBuild directory 
     app.use(express.static(paths.appBuild)); 
     console.log('Static build directory now being served, paths.appBuild: ', paths.appBuild); 

     // Serve the static HTML file from express 
     console.log('Adding static path to Express routing...'); 
     app.get('*', function(req, res) { 
      res.sendFile(paths.appHtml); 
      console.log('Path serving HTML at paths.appHTML: ', paths.appHtml); 
     }); 
     // List out which port is being used and listen for changes on the server 
     app.listen(process.env.PORT || 9004, function(){ 
      console.log('Express server listening on port %d in %s mode', (process.env.PORT || 9004), app.settings.env); 
     }); 
    } 
    console.log(); 
}); 
+1

它可以与缩小一个问题,用的WebPack重整,尽量避免缩小和美国的轧液:在您的UglifyJsPlugin假,看看是否有帮助。 –

+0

谢谢@MrJSingh我想出我的问题是什么(在2.5天之后...)。 Webpack使用了错误的publicPath。当它应该刚刚使用资源的绝对路径时,它正在使用相对路径。因此,注入的脚本标记导致错误的路径来为css和js加载它们。我会用分辨率更新我的原始帖子。 – retrospct

+4

请回答,以便其他人可以受益? –

回答

0

在webpack.config.prod.js文件中,输出:publicPath:value被设置为变量publicPath,该变量是从create-react-app弹出的代码的一部分。我没有完全理解publicPath变量将解析为什么而重用它。当我需要的是'/'的相对路径时,它正在吐出github-username/repo-name的路径。

我没有发现index.html中注入的css + js标记是不正确的路径,因为控制台中报告的错误只是表示语法错误,所以它必须是CSS和JS没有加载到这一页。我更正了使用'/'的路径,作为paths.appBuild文件夹的相对路径,其中所有静态资产都存在并被提供。

这叠后帮助,以及:Webpack publicPath

// variables from the create-react-app eject, will be removing these from my webpack.config.prod.js file 
var homepagePath = require(paths.appPackageJson).homepage; 
var publicPath = homepagePath ? url.parse(homepagePath).pathname : '/'; 
if (!publicPath.endsWith('/')) { 
    // Prevents incorrect paths in file-loader 
    publicPath += '/'; 
} 

console.log('homepagePath: ', homepagePath); // Resolves to git repo url 
console.log('publicPath: ', publicPath); // Resolves to /retrospct/tellus-aerospace/ 

module.exports = { 
    bail: true, 
    devtool: 'source-map', 
    entry: [ 
    require.resolve('./polyfills'), 
    path.join(paths.appSrc, 'index') 
    ], 
    output: { 
    path: paths.appBuild, 
    filename: 'static/js/[name].[chunkhash:8].js', 
    chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js', 
    publicPath: '/' // Previously this was the variable publicPath set above 
    }, 
+0

“当我需要的是'/'的相对路径用于我的目的时,它正在吐出github-username/repo-name的路径。” CRA中的'publicPath'由您在'package.json'中设置的'homepage'决定。你设定了什么'主页'?如果你设置了你部署的网站的URL,一切都会起作用。 –

相关问题