Webpack缩小了分发文件问题

时间:2015-12-15 17:24:51

标签: angularjs webpack webpack-dev-server

首先,我要说我是一个webpack新手,我已经使用这个很棒的工具2周了,我已经成功实现了我需要的一切,除此之外。

在这里达成协议:在我的公司,我们正在尝试将一组通用的输入,组件和通用css抽象到托管在单独存储库中的模块,以便它可以作为我们其他模块中的供应商,它& #39;名为 Mandioca 。我们所有的应用程序都是使用Angularjs框架开发的,所以它是一个角度模块。

我将所有内容捆绑在一起包含所有.js文件的缩小文件,并将其输出到名为dist的文件夹中。没什么大不了的。

当我尝试在任何其他模块中导入mandioca时会出现问题。我收到了这个例外:TypeError: Failed to construct 'WebSocket': Please use the 'new' operator, this DOM object constructor cannot be called as a function.

我认为这是缩小文件中的一个问题,因为当我停止在模块的依赖项上导入Mandioca时,错误消失了:

// Exception :(
angular.module('app', [
    'Mandioca',
    // (...other dependencies)
]);

// Everything OK
angular.module('app', [
    // (...other dependencies)
]);

我潜入了webpack配置文档和angular + webpack cookbook,遇到了一些有趣的东西,遗憾的是没有解决我的问题:

指定externals

externals: {
  angular: 'angular',
}

指定output libraryTarget选项:

config.output = {
  path: path.join(__dirname, distFolder),
  filename: (isBuild ? minJs : '[name].bundle.js'),
  libraryTarget: 'umd' // <--- here's the tweak
};

要记住的其他一些事情:

  • Mandioca模块正常运行dev任务,因此使用缩小文件进行开发而不会崩溃。
  • 所有其他模块通常运行开发任务
  • 我正在使用webpack-dev-server完成这些任务。

Mandioca的Webpack文件:

&#13;
&#13;
// webpack stuff
import webpack from 'webpack';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import WebpackNotifierPlugin from 'webpack-notifier';
// import CopyWebpackPlugin from 'copy-webpack-plugin';

// postcss
import rucksack from 'rucksack-css';
import cssnano from 'cssnano';
import nested from 'postcss-nested';
import mixins from 'postcss-mixins';
import simpleVars from 'postcss-simple-vars';
import cssnext from 'postcss-cssnext';
import postcssImport from 'postcss-import';

import vendors from './vendors.json';
import path from 'path';

export default function makeWebpackConfig(options) {
  const vendorsDir = path.join(__dirname, 'node_modules');
  const excludeVendors = /node_modules/;
  const distFolder = 'dist';
  const minJs = 'mandioca.min.js';
  const minCss = 'mandioca.min.css';
  const devEntry = './app/app.dev.js';
  const distEntry = './app/app.dist.js';
  const isTest = !!options.TEST;
  const isBuild = !!options.BUILD;
  const isDev = !isBuild && !!options.DEV;
  const isDevProd = isBuild && !!options.DEV;

  const getCssLoader = (build) => {
    let baseStr = 'css?sourceMap!postcss';

    return build ? ExtractTextPlugin.extract('style', baseStr) : 'style!' + baseStr;
  };

  const esLintPreLoader = {
    test: /\.js$/,
    loader: 'eslint',
    exclude: excludeVendors
  };

  const jsLoader = {
    test: /\.js$/,
    loaders: ['ng-annotate', 'babel'],
    exclude: excludeVendors
  };

  const cssLoader = {
    test: /\.css$/,
    loader: getCssLoader(isBuild),
    exclude: excludeVendors
  };

  const vendorsCssLoader = {
    test: /\.css$/,
    loader: 'style!css?sourceMap',
    include: excludeVendors
  };

  const filesLoader = {
    test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$/,
    loader: 'file',
    exclude: excludeVendors
  };

  const htmlLoader = {
    test: /\.html$/,
    loaders: ['ngtemplate', 'html'],
    exclude: excludeVendors
  };

  const config = {
    resolve: {
      alias: {}
    },
    plugins: [],
    entry: {
      app: ((isBuild && !isDevProd) ? distEntry : devEntry),
      vendor: []
    },
    module: {},
    externals: {
      angular: 'angular',
    }
  };

  config.output = {
    path: path.join(__dirname, distFolder),
    filename: (isBuild ? minJs : '[name].bundle.js'),
    libraryTarget: 'umd'
  };

  if (!isBuild && (isDev || isDevProd)) {
    config.module.noParse = [];
    vendors.forEach((vendor) => {
      let vendorPath = path.resolve(vendorsDir, vendor);
      // config.module.noParse.push(vendorPath);
      config.entry.vendor.push(vendorPath);
      config.resolve.alias[vendor.split(path.sep)[0]] = vendorPath;
    });
  }

  if (!isTest) {
    // Reference: https://github.com/ampedandwired/html-webpack-plugin
    // Render index.html
    config.plugins.push(
      new HtmlWebpackPlugin({
        template: './index.html',
        inject: true,
        production: isBuild,
      }),
      new webpack.ProvidePlugin({
        moment: 'moment',
        R: 'ramda',
        CPF: 'cpf_cnpj'
      }),
      new webpack.optimize.CommonsChunkPlugin({
        name: 'vendor',
        filename: (isBuild && !isDevProd) ? minJs : '[name].bundle.js',
      }),
      // Reference: https://github.com/Turbo87/webpack-notifier
      // Pops a notification on error
      new WebpackNotifierPlugin(),
      new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false }})
    );
  }

  config.postcss = function(webp) {
    let cssnanoOpt = {
      discardUnused: false,
      zindex: false
    };
    let rucksackOpt = { autoprefixer: true };

    let devPlugins = [
      postcssImport({ addDependencyTo: webp }),
      mixins,
      nested,
      simpleVars,
      rucksack(rucksackOpt),
      cssnext
    ];
    let prodPlugins = [cssnano(cssnanoOpt)];

    let plugins;
    if (isBuild) {
      plugins = devPlugins;
    } else {
      plugins = devPlugins.concat(prodPlugins);
    }

    return plugins;
  };

  config.module.preLoaders = [esLintPreLoader];
  config.module.loaders = [jsLoader, cssLoader, htmlLoader, filesLoader];

  if (isBuild || isDevProd) {
    config.plugins.push(new ExtractTextPlugin(minCss));
  }

  if (isDevProd || isDev) {
    config.module.loaders.push(vendorsCssLoader);
  }

  return config;
}
&#13;
&#13;
&#13;

我不知道,但也许这不是webpack的责任。无论如何,任何可能导致我走出阻碍者的信息我都会非常高兴。

1 个答案:

答案 0 :(得分:0)

快速浏览一下你的webpack配置我在CommonsChunks插件上发现了一个错误。您将生成的CommonsChunks文件命名为与输出条目文件相同的名称。因此,输出文件(带有您的代码)将被CommonsChunks文件替换。

如果您要分发库,则不需要供应商文件,因此我会尝试删除CommonsChunk插件,看看它是否有效。