我有webpack包大小问题,这是由sass样式引起的......
我有很多angular2组件,我使用materialize-css库设计。我使用@extend
而不是将materialize-css类放在我的html中来封装来自html本身的库。
我遇到的问题是使用webpack的包大小非常大,因为每个组件的sass都会导入materialize-css包,并且因为组件的样式是使用raw
加载器加载的,所以它会嵌入到bundle js文件中。所以我得到的是每个组件具有相同materialize-css样式的大包。
仅仅是为了比较我编译了我的应用程序和注释掉的所有样式,当包含样式时,包大小为1.08MB,它是5.26MB
有人能指出我正确的解决方案吗?
谢谢!
编辑: 我的webpack定义:
Webpack.common:
import * as webpack from 'webpack';
import {Configuration} from 'webpack';
import * as path from 'path';
import {PathHelper} from '../../common/pathHelper';
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
process.env.ENV = process.env.NODE_ENV;
export var webpackCommonConfiguration: Configuration = {
entry: {
'polyfills': './src/app/polyfills.ts',
'app': './src/app/app.ts',
'signin': './src/app/signinApp.ts',
'vendor': './src/app/vendor.ts',
'design': './src/app/design.scss'
},
resolve: {
extensions: ['', '.ts', '.js', 'scss']
},
module: {
loaders: [
{
test: /\.ts$/,
loader: 'ts'
},
{
test: /\.html$/,
loader: 'html'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file?name=assets/[name].[hash].[ext]'
},
{
test: /\.scss$/,
exclude: PathHelper.getPathFromRoot('src', 'app', 'modules'),
loader: ExtractTextPlugin.extract('style', 'css!resolve-url!sass?sourceMap')
},
{
test: /\.scss$/,
include: PathHelper.getPathFromRoot('src', 'app', 'modules'),
loader: 'raw!sass'
},
{
test: /\.css$/,
exclude: PathHelper.getPathFromRoot('src', 'app', 'modules'),
loader: ExtractTextPlugin.extract('style', 'css!resolve-url!css?sourceMap')
},
{
test: /\.css$/,
include: PathHelper.getPathFromRoot('src', 'app', 'modules'),
loader: 'raw!resolve-url'
}
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'signinCommon',
chunks: ['signin', 'vendor'],
minChunks: Infinity
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'homeCommon',
chunks: ['app', 'vendor'],
minChunks: Infinity
}),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(process.env.NODE_ENV)
}
}),
new webpack.ProvidePlugin({
// Required for the velocity plugin to be loaded correctly (used in materialize css)
"window.$": "jquery",
"window.jQuery": "jquery",
"root.jQuery": "jquery"
}),
new HtmlWebpackPlugin({
template: PathHelper.getPathFromRoot('src', 'app', 'views', 'signin.html'),
filename: 'signin.html',
chunks: ['polyfills', 'signinCommon', 'design', 'vendor', 'signin']
}),
new HtmlWebpackPlugin({
template: PathHelper.getPathFromRoot('src', 'app', 'views', 'home.html'),
filename: 'home.html',
chunks: ['polyfills', 'homeCommon', 'design', 'vendor', 'app']
})
]
}
Webpack.prod:
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
import * as webpack from 'webpack';
import {Configuration} from 'webpack';
import {webpackCommonConfiguration} from './webpack.common.config'
import {PathHelper} from '../../common/pathHelper';
interface IProductionConfiguration extends Configuration {
htmlLoader: any;
}
var config: IProductionConfiguration = {
devtool: 'source-map',
output: {
path: PathHelper.getPathFromRoot('dist'),
publicPath: '/dist/',
filename: '[name].[hash].js',
chunkFilename: '[id].[hash].chunk.js'
},
htmlLoader: {
minimize: false // workaround for ng2
},
plugins: [
new webpack.NoErrorsPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin('[name].[hash].css')
]
}
export var webpackProductionConfig: Configuration =
webpackMerge(webpackCommonConfiguration, config);
EDIT2: 组件示例:
credits.component.ts:
import {Component} from '@angular/core';
@Component({
selector: 'credits',
template: require('./credits.component.html'),
styles: [require('./credits.component.scss')]
})
export class CreditsComponent {
}
credits.component.html:
<footer class="page-footer credits-footer">
<div class="footer-copyright">
<div class="container">
© 2016 Created by Slava Shpitalny
</div>
</div>
</footer>
credits.component.scss:
@import '~materialize-css/sass/materialize.scss';
:host{
.page-footer.credits-footer{
@extend .blue;
margin: 0;
padding: 0;
}
}
答案 0 :(得分:0)
不要捆绑到单个文件。像一个供应商一个分开捆绑,一个用于pollyfills,一个用于app,一个用于css。使用{{1}}插件创建自己的css文件。使用webpack块可以让生活更轻松。对大型应用程序使用代码拆分。
在生产模式下,您可以使用一些插件来缩小捆绑包,删除注释,删除未使用的代码。
答案 1 :(得分:0)
您可以在主应用组件上使用ViewEncapsulation.None
,并将Materialise.scss导入到您应用的SCSS文件中。然后它将全局可用,您无需将其导入其他组件。
例如,您的应用组件可能如下所示:
import { ViewEncapsulation } from '@angular/core';
@Component({
selector: 'app',
encapsulation: ViewEncapsulation.None,
styles: [require('./app.scss')],
template: require('./app.html')
})
...只有您的主应用程序的SCSS文件才会包含导入:
@import '~materialize-css/sass/materialize.scss';
注意:您可以只导入您使用的Materialize组件,而不是导入materialize.css。这样可以提高效率。
如果您想在子组件中使用变量/ mixin,可以单独导入它们(但不要导入整个Materialise scss!)。
例如,子组件可能会导入_variables.scss
和_mixins.scss
,而不仅仅是materialize.scss
。
例如:
@import '~materialize-css/sass/components/_mixins.scss';
@import '~materialize-css/sass/components/_variables.scss';
不要忘记,vars / mixins不会被导出,只会导出SCSS的CSS结果,所以如果不使用它们就不会添加到文件大小(不同于包含批量的主要Materialize.scss文件)也是CSS课程)