如何使用 webpack、typescript、phaser 和 angular 配置全局 css 和 sass 样式表

Nek*_*Nek 2 css sass typescript webpack angular

以下配置是手工制作的,以支持标题中给出的所有技术(webpack、typescript、phaser 和 angular)。

它适用于角度组件样式表。但看起来不可能包含全局样式表。下面是相关的配置文件:

HTML文件:

<!-- src/index.html -->
<!DOCTYPE html>
<html>
  <head>
    <base href="/">
    <meta charset="UTF-8">
    <!-- it's included here! -->
    <link rel="stylesheet" href="styles/main.css">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body>
    <app-root></app-root>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

CSS文件:

/*
src/styles/main.css
This file is correctly loaded in dev environment. When I build the project it disapear. :(
*/
body {
    background: #253050 url('../assets/design/main_background.jpg') no-repeat center;
}
Run Code Online (Sandbox Code Playgroud)

和 webpack 配置:

// config/webpack.common.js
'use strict';

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

var distDir = path.resolve(__dirname, '../dist');

// Phaser webpack config
const phaserModule = path.join(__dirname, '/../node_modules/phaser-ce/');
const phaser = path.join(phaserModule, 'build/custom/phaser-split.js');
const pixi = path.join(phaserModule, 'build/custom/pixi.js');
const p2 = path.join(phaserModule, 'build/custom/p2.js');

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

    // What files webpack will manage
    resolve: {
        extensions: ['.js', '.ts', '.tsx'],
        alias: {
            'phaser': phaser,
            'pixi': pixi,
            'p2': p2
        }
    },
    output: {
        path: distDir,
        filename: '[name]_bundle.js'
    },

    module: {
        rules: [
            { test: /assets(\/|\\)/, use: [ 'file-loader' ] },
            {
                test: /\.tsx?$/,
                // ts-loader loads typescript files
                // angular2-template-loader is needed to load component templates
                loaders: ['ts-loader', 'angular2-template-loader'],
                exclude: [
                    /.+phaser-ce\/typescript\/.+\.ts$/,
                    /typescript\/.+\.d\.ts$/
                ]
            },
            {
              test: /\.html$/,
              loader: 'html-loader'
            },

            // to-string-loader is for css loaded by angular components
            // .... and loading angular css work as expected.
            { test: /\.css$/, loaders: ['to-string-loader', 'css-loader'] },
            {
              test: /\.scss$/, // I'd like so much sass work but guess what... it doesn't!
              use: ['to-string-loader', 'css-loader', 'sass-loader']
            },

            // Because phaser and its dependencies are not made for TypeScript and webpack
            { test: /pixi\.js/, use: [{loader: 'expose-loader', options: 'PIXI'}] },
            { test: /phaser-split\.js$/, use: [{loader: 'expose-loader', options: 'Phaser'}] },
            { test: /p2\.js/, use: [{loader: 'expose-loader', options: 'p2'}] }
        ]
    },

    plugins: [
        new webpack.ContextReplacementPlugin(
            // The (\\|\/) piece accounts for path separators in *nix and Windows

            // For Angular 5, see also https://github.com/angular/angular/issues/20357#issuecomment-343683491
            /\@angular(\\|\/)core(\\|\/)esm5/,
            helpers.root('src'), // location of your src
            {
              // your Angular Async Route paths relative to this root directory
            }
          ),
        new CleanWebpackPlugin([distDir]),
        new HtmlWebpackPlugin({
            template: 'src/index.html',
            chunksSortMode: function(a, b) {
                // set the load order !
                var order = ["polyfills", "app"];
                return order.indexOf(a.names[0]) - order.indexOf(b.names[0]);
            }
        })
    ]
};
Run Code Online (Sandbox Code Playgroud)

这是 webpack.prod.js 配置:

module.exports = merge(common, {
    devtool: 'source-map',
    plugins: [
        // stops the build if there is an error
        new webpack.NoEmitOnErrorsPlugin(),
        new UglifyJSPlugin({sourceMap: true}),
        // extracts embedded css as external files, adding cache-busting hash to the filename
        new ExtractTextPlugin('[name].[hash].css'),
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('production')
        })
    ]
});
Run Code Online (Sandbox Code Playgroud)

当我运行webpack --config config/webpack.prod.js全局CSS未加载时,没有错误。只是没有CSS。

也可以随意解释如何加载 SCSS,因为即使在我的开发模式下它也不起作用。

谢谢!

Nek*_*Nek 5

我终于让它工作了。所以这是我所做的更改:

1) style.css 的路径现在在 css/scss 子句中被忽略。

{
  exclude: path.resolve(__dirname, '../src/styles'),
  test: /\.css$/, loaders: ['to-string-loader', 'css-loader']
},
{
  exclude: path.resolve(__dirname, '../src/styles'),
  test: /\.scss$/,
  use: ['to-string-loader', 'css-loader', 'sass-loader']
}
Run Code Online (Sandbox Code Playgroud)

2)我为CSS添加了一个新的入口文件

entry: {
  'polyfills': './src/polyfills.ts',
  'app': './src/main.ts',
  'css': './src/styles/main.css'
}
Run Code Online (Sandbox Code Playgroud)

3)它有效,因为我还配置了一个使用 ExtractTextPlugin 的新规则

{
  test: /\.css$/,
  exclude: path.resolve(__dirname, '../src/app'),
  use: ExtractTextPlugin.extract({
    fallback: 'style-loader',
    use: 'css-loader'
  })
}
Run Code Online (Sandbox Code Playgroud)

请注意,这也有效,因为 prod 配置指定new ExtractTextPlugin('[name].[hash].css')为插件。(这意味着您需要将其添加到公共配置中以避免在开发环境中出现任何错误)