Webpack babel配置服务器和客户端javascript?

时间:2016-05-21 23:30:02

标签: javascript webpack babeljs

我正在试图找出如何使用单个webpack配置文件,该文件适用于使用es2015预设转换服务器(node.js)js和客户端js。目前,我必须专门设置“target:'node'”才能正确处理基于节点的文件。如果我不这样做,那么webpack会根据默认的“target:'web'”进行转换。然后报告错误,因为明确导入的“mysql”模块不适用于Web。

如何将两者统一到同一个配置文件中,以便单独转换服务器和客户端js?或者我是否需要完全独立的配置?

示例webpack.config.js

'use strict';

var path = require('path');
var webpack = require('webpack');

module.exports = {
  target: 'node',
  resolve: {
    root: path.resolve(__dirname),
    extensions: ['', '.js']
  },
  entry: [
    'babel-polyfill',
    './index.js',
  ],
  output: {
    filename: 'bundle.js'       
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          presets: ['es2015']
        }
      }
    ]
  }
};

示例js代码

import 'babel-polyfill';
import mysql from 'mysql';

class Test {
  constructor () {

  }

  get read () {

  }
};

1 个答案:

答案 0 :(得分:31)

您可以为Webpack传递多个配置以同时处理。只需返回一组配置对象。

export default [
  { 
    // config 1 here
  },
  {
    // config 2 here
  },
];

额外提示:如果您使用.babel.js作为配置文件的扩展名,Webpack将为您运行Babel,这允许您在Webpack配置中使用ES6。

Bonus:下面的代码段



// Source: https://gist.github.com/Ambroos/f23d517a4261e52b4591224b4c8df826

import webpack from 'webpack';
import path from 'path';

import CleanPlugin from 'clean-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import AssetsPlugin from 'assets-webpack-plugin';
import CompressionPlugin from 'compression-webpack-plugin';
import autoprefixer from 'autoprefixer';
import rucksack from 'rucksack-css';
import cssnano from 'cssnano';
import moment from 'moment';

const sharedPlugins = [
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /nl/),
    new webpack.optimize.AggressiveMergingPlugin({}),
    new webpack.optimize.OccurenceOrderPlugin(true),
    new webpack.optimize.UglifyJsPlugin({
        compress: {
            drop_console: true,
            screw_ie8: true,
            sequences: true,
            properties: true,
            dead_code: true,
            drop_debugger: true,
            conditionals: true,
            comparisons: true,
            evaluate: true,
            booleans: true,
            loops: true,
            unused: true,
            if_return: true,
            join_vars: true,
            cascade: true,
            negate_iife: true,
            hoist_funs: true,
            warnings: false,
        },
        mangle: {
            screw_ie8: true,
        },
        output: {
            screw_ie8: true,
            preamble: '/* Website - ' + moment().format() + ' */',
        },
    }),
];

const sharedServerPlugins = [
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /nl/),
    new webpack.optimize.AggressiveMergingPlugin({}),
    new webpack.optimize.OccurenceOrderPlugin(true),
    new webpack.optimize.UglifyJsPlugin({
        compress: {
            drop_console: false,
            screw_ie8: true,
            sequences: true,
            properties: true,
            dead_code: true,
            drop_debugger: false,
            conditionals: true,
            comparisons: true,
            evaluate: true,
            booleans: true,
            loops: true,
            unused: true,
            if_return: true,
            join_vars: true,
            cascade: true,
            negate_iife: true,
            hoist_funs: true,
            warnings: false,
        },
        mangle: {
            screw_ie8: true,
        },
        output: {
            screw_ie8: true,
            preamble: '/* Website - ' + moment().format() + ' */',
        },
    }),
];

const PATHS = {
    build: path.resolve(__dirname, '..', 'build'),
    sourcemaps: path.resolve(__dirname, '..', 'build', 'sourcemaps'),
    browserSource: path.resolve(__dirname, '..', 'src', 'browser', 'index.js'),
    browserBuild: path.resolve(__dirname, '..', 'build', 'browser'),
    serverSource: path.resolve(__dirname, '..', 'src', 'server', 'index.js'),
    serverAssetsSource: path.resolve(__dirname, '..', 'src', 'server', 'assets', 'index.js'),
    serverBuild: path.resolve(__dirname, '..', 'build', 'server'),
};

export default [
    // Browser
    {
        entry: { browser: PATHS.browserSource },
        output: {
            path: PATHS.browserBuild,
            filename: 's/[chunkhash].js',
            chunkFilename: 's/async-[chunkhash].js',
            publicPath: '/',
            sourceMapFilename: '../sourcemaps/browser/[file].map',
        },
        devtool: 'hidden-source-map',
        plugins: [
            new AssetsPlugin({
                prettyPrint: true,
                path: path.resolve(PATHS.build, 'browserAssets'),
                filename: 'index.js',
                processOutput: assets => `module.exports = ${JSON.stringify(assets, null, '    ')};`,
            }),
            new CleanPlugin([PATHS.browserBuild, PATHS.sourcemaps], path.resolve(PATHS.build, 'browserAssets')),
            new ExtractTextPlugin('s/[contenthash].css'),
            new CompressionPlugin({
                asset: '{file}.gz',
                algorithm: 'gzip',
                regExp: /\.js$|\.html$|\.css$|\.svg$|\.eot$|\.xml$/,
                threshold: 1400,
                minRation: 0.8,
            }),
            new webpack.DefinePlugin({
                'process.env': {
                    NODE_ENV: JSON.stringify('production'),
                    WEBPACK_ENV: JSON.stringify('browser'),
                    APP_ENV: (process.env.APP_ENV && JSON.stringify(process.env.APP_ENV)) || undefined,
                },
            }),
        ].concat(sharedPlugins),
        externals: [
            { browserConfig: 'var websiteBrowserConfig' },
            { programs: 'var programs' },
        ],
        module: {
            loaders: [
                {
                    test: /\.jsx?$/,
                    exclude: /node_modules/,
                    loader: 'babel',
                },
                {
                    test: /\.json$/,
                    loader: 'json',
                },
                {
                    test: /\.scss$/,
                    loader: ExtractTextPlugin.extract(
                        'style',
                        [
                            'css?importLoaders=2&localIdentName=css-module-[hash:base64]',
                            'postcss',
                            'sass',
                        ]
                    ),
                },
                {
                    test: /\.(gif|png|jpe?g|svg|ico)$/i,
                    loaders: [
                        'url?limit=1400&name=s/i/[sha512:hash:base64:16].[ext]',
                        'image-webpack?bypassOnDebug',
                    ],
                },
                {
                    test: /isotope\-|fizzy\-ui\-utils|desandro\-|masonry|outlayer|get\-size|doc\-ready|eventie|eventemitter/,
                    loader: 'imports?define=>false&this=>window',
                },
                {
                    test: /flickity/,
                    loader: 'imports?define=>false&this=>window',
                },
                {
                    test: /node_modules\/unipointer/,
                    loader: 'imports?define=>undefined',
                },
            ],
        },
        postcss: () => {
            return [rucksack, autoprefixer, cssnano];
        },
    },

    // Server assets
    {
        entry: { assets: PATHS.serverAssetsSource },
        target: 'node',
        output: {
            path: PATHS.browserBuild,
            libraryTarget: 'commonjs',
            filename: '../serverAssets/index.js',
            publicPath: '/',
        },
        plugins: [
            // assetsWriter,
            new CompressionPlugin({
                asset: '{file}.gz',
                algorithm: 'gzip',
                regExp: /\.js$|\.html$|\.css$|\.svg$|\.eot$|\.xml$/,
                threshold: 1400,
                minRation: 0.8,
            }),
            new webpack.DefinePlugin({
                'process.env': {
                    NODE_ENV: JSON.stringify('production'),
                    WEBPACK_ENV: JSON.stringify('assets'),
                    APP_ENV: (process.env.APP_ENV && JSON.stringify(process.env.APP_ENV)) || undefined,
                },
            }),
        ].concat(sharedPlugins),
        module: {
            loaders: [
                {
                    test: /\.jsx?$/,
                    exclude: /node_modules/,
                    loader: 'babel',
                },
                {
                    test: /\.json$/,
                    loader: 'json',
                },
                {
                    test: /\.(gif|png|jpe?g|svg|ico)$/i,
                    loaders: [
                        'url?limit=1400&name=s/i/[sha512:hash:base64:16].[ext]',
                        'image-webpack?bypassOnDebug',
                    ],
                },
            ],
        },
    },

    // Server
    {
        entry: PATHS.serverSource,
        target: 'node',
        output: {
            path: PATHS.build,
            libraryTarget: 'commonjs',
            filename: 'server/server.js',
            publicPath: '/s/',
            sourceMapFilename: 'sourcemaps/browser/[file].map',
        },
        externals: [
            { serverAssets: '../serverAssets/index.js' },
            { browserAssets: '../browserAssets/index.js' },
            { vrtConfig: '../../env_vars.js' },
            /^(?!\.|\/).+/i,
            /webpack-assets\.json/,
        ],
        plugins: [
            new CleanPlugin(PATHS.serverBuild),
            new webpack.DefinePlugin({
                'process.env': {
                    NODE_ENV: JSON.stringify('production'),
                    WEBPACK_ENV: JSON.stringify('server'),
                    APP_ENV: (process.env.APP_ENV && JSON.stringify(process.env.APP_ENV)) || undefined,
                },
            }),
        ].concat(sharedServerPlugins),
        node: {
            __dirname: false,
            __filename: false,
        },
        module: {
            loaders: [
                {
                    test: /\.jsx?$/,
                    exclude: /node_modules/,
                    loader: 'babel',
                },
                {
                    test: /\.json$/,
                    loader: 'json',
                },
            ],
        },
    },
];




这是我们在我们的一个站点中使用的配置,它具有部分共享的代码库和部分共享资源。它由三个Webpack构建组成:

  • 浏览器
  • 服务器资产(将在服务器生成的HTML中引用的图像/字体/ ...)
  • 服务器代码(节点)

服务器代码有一些特殊属性:

  • target: 'node'(Webpack需要这个)
  • output.libraryTarget: 'commonjs'(使Webpack对非捆绑库使用commonjs)
  • externals: [ /^(?!\.|\/).+/i, ](使Webpack不捆绑node_modules中的任何内容,或任何不是相对路径的内容(以./开头)

这种组合使Webpack只处理您自己的代码,并通过require访问其他模块和库。这意味着使用本机绑定的依赖关系不会因为它们不被捆绑而中断。

相关问题