2017-04-14 31 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加載器文件。它的工作。 –

相關問題