TypeScript webpack-chain entry示例

说明

typescript webpack-chain entry示例是从最受好评的开源项目中提取的实现代码,你可以参考下面示例的使用方式。

编程语言: TypeScript

命名空间/包名称: webpack-chain

示例#1
文件: config.common.ts 项目: Kenneth-Chen/egg

export function init(options: EnvOptions): Config {
  const ENV = options.ENV || "dev";
  const ROOT = options.ROOT || __dirname;
  // const TEST = options.TEST || false;

  const config = new Config();
  // Check if git repo exists
  const gitRepoExists = fs.existsSync("../.git");

  // set all common configurations here
  config
    .entry("main")
      .add("./src/main.ts");

  config
    .output
      .path(path.join(ROOT, "dist", ENV))
      .filename("main.js")
      .pathinfo(false)
      .libraryTarget("commonjs2")
      .sourceMapFilename("[file].map")
      .devtoolModuleFilenameTemplate("[resource-path]");

  config.devtool("source-map");

  config.target("node");

  config.node.merge({
    Buffer: false,
    __dirname: false,
    __filename: false,
    console: true,
    global: true,
    process: false,
  });

  config.watchOptions({ ignored: /node_modules/ });

  config.resolve
    .extensions
      .merge([".webpack.js", ".web.js", ".ts", ".tsx", ".js"]);

  // see for more info about TsConfigPathsPlugin
  // https://github.com/s-panferov/awesome-typescript-loader/issues/402
  config.resolve.plugin("tsConfigPaths") // name here is just an identifier
    .use(TsConfigPathsPlugin);

  config.externals({
    // webpack will not try to rewrite require("main.js.map")
    "main.js.map": "main.js.map",
  });

  /////////
  /// Plugins

  //   NOTE: do not use 'new' on these, it will be called automatically
  // this plugin is for typescript's typeschecker to run in async mode
  config.plugin("tsChecker")
    .use(CheckerPlugin);

  // this plugin wipes the `dist` directory clean before each new deploy
  config.plugin("clean")
    .use(CleanWebpackPlugin, [    // arguments passed to CleanWebpackPlugin ctor
      [ `dist/${options.ENV}/*` ],
      { root: options.ROOT },
    ]);

  // you can use this to define build toggles; keys defined here
  // will be replaced in the output code with their values;
  // Note that because the plugin does a direct text replacement,
  //   the value given to it must include actual quotes inside of the
  //   string itself. Typically, this is done either with either
  //   alternate quotes, such as '"production"', or by using
  //   JSON.stringify('production').
  // Make sure to let typescript know about these via `define` !
  // See https://github.com/kurttheviking/git-rev-sync-js for more git options
  config.plugin("define")
    .use((webpack.DefinePlugin as Config.PluginClass), [{
      PRODUCTION: JSON.stringify(true),
      __BUILD_TIME__: JSON.stringify(Date.now()),  // example defination
      __REVISION__: gitRepoExists ? JSON.stringify(git.short()) : JSON.stringify(""),
    }]);

  config.plugin("screeps-source-map")
    .use((ScreepsSourceMapToJson as Config.PluginClass));

  config.plugin("no-emit-on-errors")
    .use((webpack.NoEmitOnErrorsPlugin as Config.PluginClass));

  /////////
  /// Modules

  config.module.rule("js-source-maps")
    .test(/\.js$/)
    .enforce("pre")
    .use("source-map")
      .loader("source-map-loader");

  config.module.rule("tsx-source-maps")
    .test(/\.tsx?$/)
    .enforce("pre")
    .use("source-map")
      .loader("source-map-loader");

  config.module.rule("compile")
    .test(/\.tsx?$/)
    .exclude
      .add(path.join(ROOT, "src/snippets"))
      .end()
    .use("typescript")
      .loader("awesome-typescript-loader")
      .options({ configFileName: "tsconfig.json" });

  config.module.rule("lint")
    .test(/\.tsx?$/)
    .exclude
      .add(path.join(ROOT, "src/snippets"))
      .add(path.join(ROOT, "src/lib"))
      .end()
    .use("tslint")
      .loader("tslint-loader")
      .options({
        configFile: path.join(ROOT, "tslint.json"),
        // automaticall fix linting errors
        fix: false,
        // you can search NPM and install custom formatters
        formatter: "stylish",
        // enables type checked rules like 'for-in-array'
        // uses tsconfig.json from current working directory
        typeCheck: false,
      });

  // return the config object
  return config;
}

示例#2
文件: config.ts 项目: leslieSie/docz

export const createConfig = (babelrc: BabelRC) => (
  args: Args,
  env: Env
): Config => {
  const { debug, host, port, protocol } = args

  const config = new Config()
  const isProd = env === 'production'
  const base = paths.servedPath(args.base)
  const dist = paths.getDist(args.dest)
  const srcPath = path.resolve(paths.root, args.src)

  /**
   * general
   */
  config.context(paths.root)
  config.set('mode', env)

  config.when(debug, cfg => cfg.devtool('source-map'))
  config.when(!isProd, cfg => cfg.devtool('cheap-module-eval-source-map'))

  config.node.merge({
    child_process: 'empty',
    dgram: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
  })

  /**
   * output
   */
  const outputProd = (output: Config.Output) =>
    output
      .filename('static/js/[name].[chunkhash:8].js')
      .sourceMapFilename('static/js/[name].[chunkhash:8].js.map')
      .publicPath(base)

  const outputDev = (output: Config.Output) =>
    output
      .filename('static/js/[name].js')
      .sourceMapFilename('static/js/[name].js.map')
      .publicPath('/')

  config.output
    .pathinfo(true)
    .path(dist)
    .when(isProd, outputProd, outputDev)
    .crossOriginLoading('anonymous')

  /**
   * optimization
   */

  config.merge({
    optimization: {
      nodeEnv: 'dev',
      namedModules: true,
      noEmitOnErrors: true,
      runtimeChunk: true,
      splitChunks: {
        chunks: 'all',
        name: 'vendors',
      },
      ...(isProd && {
        minimizer: [uglify],
      }),
    },
  })

  /**
   * entries
   */

  config
    .entry('app')
    .add(require.resolve('babel-polyfill'))
    .add(paths.indexJs)

  /**
   * resolve
   */

  config.resolve
    .set('symlinks', true)
    .alias.set(
      '@babel/runtime',
      path.dirname(require.resolve('@babel/runtime/package.json'))
    )

  config.resolve.extensions
    .merge([
      '.web.js',
      '.mjs',
      '.js',
      '.json',
      '.web.jsx',
      '.jsx',
      '.mdx',
      ...(args.typescript ? ['.ts', '.tsx'] : []),
    ])
    .end()
    .modules.add('node_modules')
    .add(srcPath)
    .add(paths.root)

  config.resolveLoader
    .set('symlinks', true)
    .modules.add('node_modules')
    .add(paths.root)

  /**
   * loaders
   */

  loaders.js(config, args)
  loaders.mdx(config, args)
  args.typescript && loaders.ts(config, args)
  loaders.setupHappypack(config, args, babelrc)
  loaders.images(config)
  loaders.svg(config)
  loaders.media(config)
  loaders.fonts(config)

  /**
   * plugins
   */

  config.plugin('assets-plugin').use(manifestPlugin, [
    {
      filename: 'assets.json',
    },
  ])

  config.plugin('html-webpack-plugin').use(htmlWebpackPlugin, [
    {
      inject: true,
      template: paths.indexHtml,
      ...(isProd && {
        minify: {
          removeComments: true,
          collapseWhitespace: true,
          removeRedundantAttributes: true,
          useShortDoctype: true,
          removeEmptyAttributes: true,
          removeStyleLinkTypeAttributes: true,
          keepClosingSlash: true,
          minifyJS: true,
          minifyCSS: true,
          minifyURLs: true,
        },
      }),
    },
  ])

  const isLocalhost = host === '127.0.0.1' || host === '0.0.0.0'
  const hostname = isLocalhost ? 'localhost' : host

  config.when(!debug && !isProd, cfg => {
    cfg.plugin('webpackbar').use(webpackBarPlugin, [
      {
        color: '#41b883',
        compiledIn: false,
        name: 'Client',
      },
    ])
    cfg.plugin('friendly-errors').use(friendlyErrors, [
      {
        compilationSuccessInfo: {
          messages: [
            `You application is running at ${protocol}://${hostname}:${port}`,
          ],
        },
      },
    ])
  })

  config.plugin('injections').use(require('webpack/lib/DefinePlugin'), [
    {
      BASE_URL: JSON.stringify(base),
    },
  ])

  config.performance.hints(false)
  return config
}

展开阅读全文