2017-04-14 30 views
4

我目前有一个使用webpack并部署到Heroku的Angular(v4.0.1)应用程序。我有一个加载微调器设置为在应用程序加载时显示在页面上。目前我已将其设置为可在本地使用,但由于某种原因,当我部署到heroku时,加载微调器(或者更确切地说CSS旋转加载微调器)看起来并没有拉入。如何在应用程序加载Angular + Webpack + Heroku应用程序之前包含CSS

我尝试了一些可能的修复,但我很难弄清楚我需要改变什么才能让它在生产环境中工作,并且我在stackoverflow上找到的所有东西似乎只能在本地工作。我还应该澄清,应用程序中的所有css文件(如应用程序加载后加载的组件样式)都可以正常工作,它只是一个包含在index.html中专用于加载微调器的css文件需要在Angular应用加载之前提供。

我的文件结构(简化):

. 
+-- config/ 
+-- src/ 
| +-- app/ 
| +-- assets/ 
|  +-- icons/ 
|   +-- loading-spinner.svg 
|  +-- stylesheets/ 
|   +--- loading-spinner.css 
| +-- vendor/ 
| +-- index.html 
| +-- main.ts 
| +-- polyfills.ts 
| +-- tsconfig.json 
+-- package.json 
+-- server.js 

我的index.html

<!DOCTYPE html> 
<html> 
    <head> 
    <base href="/"> 
    <title>Stylist Suite 2.0</title> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1"> 
    <link rel="stylesheet" href="src/assets/stylesheets/loading-spinner.css"> 
    </head> 
    <body> 
    <ss-app> 
     <div class="loading-spinner ss-loading"></div> 
    </ss-app> 
    </body> 
</html> 

装载-spinner.css文件:

/* --- Loading Spinner - Needed Before App Loads ---*/ 

.loading-spinner { 
    width: 42px; 
    height: 44px; 

    background: url("../icons/loading-spinner.svg") no-repeat; 
    margin: 0 auto; 
    animation: spin 2.5s linear infinite; 

    -webkit-animation: spin 2.5s linear infinite; 
    -webkit-transform: translateZ(0); 
    -ms-transform: translateZ(0); 
    transform: translateZ(0); 
} 

@keyframes spin { 
    0% { transform: rotate(0deg); } 
    100% { transform: rotate(360deg); } 
} 

.loading-spinner .ss-loading { 
    position: fixed; 
    top:50%; 
    left:50%; 
    margin-left:-21px; 
    margin-top: -22px; 
    align-self: center; 
    justify-self: center; 
} 

我webpack.common.js (位于config /下)

var webpack = require('webpack'); 
var HtmlWebpackPlugin = require('html-webpack-plugin'); 
var ExtractTextPlugin = require('extract-text-webpack-plugin'); 
var helpers = require('./helpers'); 

module.exports = { 
    entry: { 
    'polyfills': './src/polyfills.ts', 
    'vendor': './src/vendor/vendor.ts', 
    'app': './src/main.ts' 
    }, 

    resolve: { 
    extensions: ['.ts', '.js'] 
    }, 

    devtool: 'source-map', 

    module: { 
    rules: [ 
     { 
     test: /\.html$/, 
     loader: 'html-loader' 
     }, 
     { 
     test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/, 
     loader: 'file-loader?name=assets/[name].[hash].[ext]' 
     }, 
     { 
     test: /\.css$/, 
     exclude: helpers.root('src', 'app'), 
     loader: ExtractTextPlugin.extract({ loader: 'style-loader', use: 'css-loader?sourceMap' }) 
     }, 
     { 
     test: /\.css$/, 
     include: helpers.root('src', 'app'), 
     loader: 'raw-loader' 
     }, 
     { 
     test: /\.css$/, 
     exclude: helpers.root('src', 'assets'), 
     loader: ExtractTextPlugin.extract({ loader: 'style-loader', use: 'css-loader?sourceMap' }) 
     }, 
     { 
     test: /\.css$/, 
     include: helpers.root('src', 'assets'), 
     loader: 'raw-loader' 
     }, 
     { 
     test: /\.scss$/, 
     exclude: /node_modules/, 
     loaders: ['to-string-loader', 'style-loader', 'css-loader', 'resolve-url-loader', 'sass-loader?sourceMap'] 
     }, 
     { 
     test: /\.ts$/, 
     loaders: [ 
      { 
      loader: 'awesome-typescript-loader', 
      options: { configFileName: helpers.root('src', 'tsconfig.json') } 
      }, 'angular2-template-loader' 
     ] 
     } 
    ] 
    }, 

    plugins: [ 
    // Workaround for angular/angular#11580 
    new webpack.ContextReplacementPlugin(
     // The (\\|\/) piece accounts for path separators in *nix and Windows 
     /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/, 
      helpers.root('./src'), // location of your src 
     {} // a map of your routes 
    ), 

    new webpack.optimize.CommonsChunkPlugin({ 
     name: ['app', 'vendor', 'polyfills'] 
    }), 

    new HtmlWebpackPlugin({ 
     template: 'src/index.html' 
    }) 
    ] 
}; 

我webpack.dev.js(位于配置/)

var webpack = require('webpack'); 
var webpackMerge = require('webpack-merge'); 
var ExtractTextPlugin = require('extract-text-webpack-plugin'); 
var commonConfig = require('./webpack.common.js'); 
var helpers = require('./helpers'); 

module.exports = webpackMerge(commonConfig, { 
    devtool: 'cheap-module-eval-source-map', 

    output: { 
    path: helpers.root('dist'), 
    publicPath: 'http://localhost:4200/', 
    filename: '[name].js', 
    chunkFilename: '[id].chunk.js' 
    }, 

    plugins: [ 
    new ExtractTextPlugin('[name].css'), 
    new webpack.DefinePlugin({ 
     'process.env.API_APPLICATION_ID': JSON.stringify(""), 
     'process.env.REDIRECT_URL': JSON.stringify("http://localhost:4200/login"), 
     'process.env.API_BASE_URL': JSON.stringify("http://localhost:3000"), 
     'process.env.SITE_URL': JSON.stringify("http://localhost:3000") 
    }) 
    ], 

    devServer: { 
    historyApiFallback: true, 
    stats: 'minimal' 
    } 
}); 

我webpack.prod.js(位于配置/)

var webpack = require('webpack'); 
var webpackMerge = require('webpack-merge'); 
var ExtractTextPlugin = require('extract-text-webpack-plugin'); 
var commonConfig = require('./webpack.common.js'); 
var helpers = require('./helpers'); 

const ENV = process.env.NODE_ENV = process.env.ENV = 'production'; 

module.exports = webpackMerge(commonConfig, { 
    devtool: 'source-map', 

    output: { 
    path: helpers.root('dist'), 
    publicPath: '/', 
    filename: '[name].[hash].js', 
    chunkFilename: '[id].[hash].chunk.js' 
    }, 

    plugins: [ 
    new webpack.NoEmitOnErrorsPlugin(), 
    new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618 
     mangle: { 
     keep_fnames: true 
     } 
    }), 
    new ExtractTextPlugin('[name].[hash].css'), 
    new webpack.DefinePlugin({ 
     'process.env.API_APPLICATION_ID': JSON.stringify(process.env.API_APPLICATION_ID), 
     'process.env.REDIRECT_URL': JSON.stringify(process.env.REDIRECT_URL), 
     'process.env.API_BASE_URL': JSON.stringify(process.env.API_BASE_URL), 
     'process.env.SITE_URL': JSON.stringify(process.env.REDIRECT_URL) 
    }), 
    new webpack.LoaderOptionsPlugin({ 
     htmlLoader: { 
     minimize: false // workaround for ng2 
     } 
    }) 
    ] 
}); 

再次,我所有的资产(其他样式表,图标下的图像)加载罚款,一旦应用程序已加载,因为它们正在由我的webpack.common.js中的各种CSS和文件加载程序正确处理。我假设这个问题与我的webpack.prod.js文件有关,因为所有这些都可以在本地完美运行,但是我所尝试的一切似乎都没有解决问题,加载 - spinner.css文件根本就没有被加载。任何意见,将不胜感激。

+0

感谢@peeskillet我更新了它,所以它现在包含我的webpack.common。 js,webpack.dev.js和webpack.prod.js。 – NColey

回答

2

从您的配置看来,您只需按照Angular docs on webpack逐字逐句。在那些文档中,他们使用全局样式表src/assets/css/styles.css。他们引进这在AppComponent

import '../assets/css/styles.css'; 

@Component({ 
}) 
export class AppComponent { } 

这将完成是导致ExtractTextPlugin提取从(在这种情况下,CSS)文件,您importrequire,把它放在一个styles.css文件中的文本,并添加文件为<link>。输出文件名与实际文件名无关。 styles.css恰好是为ExtractTextPlugin配置的名称。

如果检查dist文件夹,并检查了index.html,你会看到这个styles.[hash].css文件添加为<link>

这就是说,你应该这样做与加载器的CSS。只需将其导入AppComponent即可。这将导致加载器css 内容进入styles.[hash].css。如果你想让装载器的CSS与其他全局样式分开,再考虑一下,因为它并不重要。无论如何,直到所有样式表加载完毕,浏览器才开始渲染。

它为dev服务器工作的原因是因为dev服务器的工作方式有点不同。它被配置为为服务器添加公共路径,以便它可以从一个位置服务器上的文件。

在这种情况下,可以从服务器访问资产。但是当您为生产而建设时,这些资产不会被转移。他们需要导入某处,因为这是webpack为最多端口工作的方式。通过导入,webpack知道这是一个应该构建用于分发的模块。

您也不需要像以前那样手动将加载器CSS添加到index.html。它只需通过导入就可以用于开发和生产。你也不需要在任何地方导入svg,因为webpack已经能够在加载器的css url中检测到它,并且在生成版本中转移它

+0

是的,当我第一次设置它时,我使用上面的应用程序组件中包含的styles.css进行了测试,但每当我尝试启动服务器时,我都收到以下错误: './src/assets/stylesheets/中出现错误loading-spinner.css 模块构建失败:未知单词(1:1)> 1 | module.exports =后面跟着styles.css文件。 现在使用loading-spinner.css也是这样,这就是为什么我要寻找包含css文件的外部方法。是否有另一种方法将它包含在app.component.ts之外? – NColey

+0

此外,我的评论上面没有足够的空间@peeskillet,但我真的很感谢你对dev和prod服务器如何在这里工作的解释。我们的应用程序自6月份以来一直在使用systemjs,现在我们只是切换到webpack,所以对我来说这有点新。 – NColey

+0

嗯。不知道这个错误。我刚测试过。我有一个项目,几乎是我提到的文档的一个逐字,并且只是添加了一个随机的css加载器文件。它的工作。 –

相关问题