我目前有一个使用webpack的Angular(v4.0.1)应用程序并部署到Heroku.我有一个加载微调器设置为在应用程序加载时显示在页面上.目前我已将其设置为本地工作,但出于某种原因,当我部署到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
Meta charset="UTF-8">
<Meta name="viewport" content="width=device-width,initial-scale=1">
loading-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',loader: 'raw-loader'
},'assets'),{
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(位于config /下)
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(位于config /下)
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',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文件有关,因为所有这些都在本地工作,但我尝试的一切似乎都没有解决问题,loading-spinner.css文件根本没有被加载.任何意见,将不胜感激.
import '../assets/css/styles.css';
@Component({
})
export class AppComponent { }
这将导致ExtractTextPlugin
从您导入或要求的(在本例中为css)文件中提取文本,将其放在styles.css文件中,并将该文件添加为< link>.输出文件名与实际文件名无关. styles.css恰好是为ExtractTextPlugin配置的名称.
如果你检查dist文件夹,并查看index.html,你会看到这个样式.[hash] .css文件被添加为< link>.
话虽这么说,你应该对加载器css做同样的事情.只需将其导入AppComponent即可.这将导致加载器css内容进入样式.[hash] .css.如果您希望将加载程序css与其他全局样式分开,请再想一想,因为它并不重要.在完成所有样式表加载之前,浏览器不会开始渲染.
它适用于开发服务器的原因是因为开发服务器的工作方式略有不同.它被配置为为服务器添加公共路径,它可以从一个位置服务器文件.
在这种情况下,可以从服务器访问资产.但是,当您为生产而构建时,这些资产不会被转移.它们需要在某处导入,因为这就是webpack在大多数端口上的工作方式.通过导入,webpack知道它是一个应该构建用于分发的模块.
您也不需要手动将加载程序css添加到index.html,就像您所做的那样.它只适用于开发和生产,只需导入即可.你也不需要在任何地方导入svg,因为webpack已经在loader css url中检测到它,并在生产版本中传输它