npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

webpackcc

v2.1.6

Published

首先必须说明一下,该工具是基于webpack2的,所以很多配置都是需要遵守webpack2规范的。如果需要安装,直接运行下面的命令就可以了。而且,我们的入口文件都是在package.json中进行配置,当执行wcf命令会自动调用下面的三种模式中的一种完成打包。

Downloads

137

Readme

说明

首先必须说明一下,该工具是基于webpack2的,所以很多配置都是需要遵守webpack2规范的。如果需要安装,直接运行下面的命令就可以了。而且,我们的入口文件都是在package.json中进行配置,当执行wcf命令会自动调用下面的三种模式中的一种完成打包。

npm install -g webpackcc//必须注意,我们局部安装的优先级要高于全局安装的

入口文件的配置:

 "entry": {
    "index": "./test/index.js"
  }

1.该工具的三种打包模式

1.1 webpack-dev-server模式(Best Performance)

这种模式你只要在wcf后添加devServer参数,表明我们的文件应该使用webpack-dev-server来完成打包,此时所有的生成文件都会在内存中,而不会写入磁盘,效率比下面两种模式高,也是最推荐的一种打包模式(该模式绕过了写本地磁盘这一步,所以文件如果改变直接从内存中读取的速度要比其他方式高得多)。同时该模式会自动在output.path路径下通过html-webpack-plugin产生一个html(内存中不可见,同时需要加上--dev表明是开发模式),并自动加载我们的所有chunk.

 wcf --devServer --dev
 //此时打开localhost:8080就会看到我们使用test/index.html作为template的页面,如果你需要修改template请使用下面的htmlTemplate参数

1.2 webpack本身的watch模式(OK performance)

这种模式使用webpack自己的watch方法来完成,监听package.json中entry配置的文件的变化。你需要添加--watch --dev。如下:

wcf --watch --dev

该模式除了会监听entry文件的变化,而且当我们自定义的webpack.config.js(通过--config传入)文件内容变化的时候会自动退出编译,要求用户重启编译过程!

1.3 webpack普通模式

此时不会监听文件的变化,只是完成webpack的一次编译然后退出!

wcf --dev

2.生产模式 vs 开发模式

2.1 开发模式

你需要通过添加--dev来开启开发模式。

如果模块本身是支持HMR的,那么我们就会采用不刷新的方式来更新页面,否则采用传统的livereload的方式。但是该模式会添加很多非用户指定的代码,如实现HMR的功能的客户端代码,所以不建议在生产模式使用。而且此时生成的css是内联的,是为了实现HMR的(style-loader完美支持HMR)!

2.2 生产模式

此时你不需要指定--dev参数,去掉即可。该模式除了下面说的Plugin和开发环境不同以外,而且不再具有HMR的功能。所以打包生产的bundle较小!而且当你每次修改文件的时候需要手动刷新页面。此时会单独生成一个css文件(集成ExtractTextPlugin),而不是在开发模式模式下将css全部内联到html中!

2.该工具的配置参数

注意,该工具的所有的配置都是基于webpack的,各个参数的意义和webpack是一致的。

2.1 cli参数

--version

表示我们的版本号

-V/--vendor

表示我们是否添加commonChunkPlugin将引用次数过多的代码抽取出一个vendor.js

-w/--watch

表示是否启动webpack的watch模式,参数值可以是一个数字,默认是200ms。

-h/--hash

表示文件名是否应该包含hash值,注意这里如果传入这个参数那么文件名都会包含chunkhash而不是hash。

--dll

此时你需要输入一个webpack.dll.js,通过这个文件我们产生一个json文件用于DllReferencePlugin

-m/--manifest <manifest.json>

此时你需要传入一个json文件给DllReferencePlugin,此时我们会自动添加DllReferencePlugin。需要了解上面两个选项可以阅读webpackDll

--publicPath

表示我们webpack的publicPath参数

--devtool

用于指定sourceMap格式,默认是"cheap-source-map"

--stj

是否在output.path路径下产生stats.json文件,该文件可以参见这里用于分析本次打包过程

--dev

是否是开发模式,如果是我们会添加很多开发模式下才会用到的Plugin

--devServer

因为该工具集成了webpack-dev-server的打包模式,可以使用这个参数开启上面所说的webpack-dev-server模式。

--config

让使用者自己指定配置文件,配置文件内容会通过webpack-merge进行合并。

2.2 webpack默认参数

entry:

我们通过在package.json中配置entry字段来表示入口文件,比如:

 "entry": {
    "index": "./test/index.js"
  }

这样就表示我们会将test目录下的index.js作为入口文件来打包,你也可以配置多个入口文件,其都会打包到output.path对应的目录下。当然,你也可以通过上面shell配置的config文件来更新或者覆盖入口文件。覆盖模式采用的就是上面说的webpack-merge。

output.path:

我们默认的打包输出路径是process.cwd()/dest,你可以通过我们的--config参数来覆盖。

loaders:

使用url-loader来加载png|jpg|jpeg|gif图片,小于10kb的文件将使用DataUrl方式内联:

{
  test: /\.(png|jpg|jpeg|gif)(\?v=\d+\.\d+\.\d+)?$/i,
  use: {
     loader:require.resolve('url-loader'),
     //If the file is greater than the limit (in bytes) the file-loader is used and all query parameters are passed to it.
     //smaller than 10kb will use dataURL
     options:{
      limit : 10000
     }
  }
 }

json文件采用json-loader加载:

{ 
   test: /\.json$/, 
   loader:require.resolve('json-loader')
}

html文件采用html-loader来加载:

{ 
    test: /\.html?$/, 
    use:{
      loader: require.resolve('html-loader'),
      options:{
      }
    }
  }

sass文件采用如下三个loader顺次加载:

{
    test: /\.scss$/,
    loaders: ["style-loader", "css-loader", "sass-loader"]
}

当然,你可以通过getWebpackDefaultConfig.js来查看更多的loader信息。其中内置了很多的功能,包括css module,压缩css,集成autoPrefixer,precss,直接import我们的css文件等等。

注意:上面任何内置的参数都是可以通过config(shell配置)文件来替换的!

3.内置plugins

为了保证开发环境的效率,在使用wcf的时候建议传入--dev表明是在开发环境中,这时候wcf会安装一些仅仅在开发环境使用的包。

开发环境独有的plugin:

HotModuleReplacementPlugin
//支持HMR
HtmlWebpackPlugin
//在output目录下产生一个index.html(生产环境下也会添加该plugin,只是不再支持HMR,并要求用户手动刷新页面)

生产环境独有的plugin:

UglifyJsPlugin//压缩JS
ImageminPlugin //压缩图片
ExtractTextPlugin//单独将css抽取出来,并要求用户手动刷新页面

共有的包:

CommonsChunkPlugin
//抽取公共的模块到common.js中
MinChunkSizePlugin
//减少chunk个数
LoaderOptionsPlugin
//兼容性要求
StatsPlugin
//shell参数传入--stj
DllPluginDync
//shell传入manifest

4.HMR功能的说明

在webpack-dev-server模式下,我们提供了HMR的功能,你不需要添加任何参数,默认开启。如果你需要体验该功能,只要在入口文件中加上下面的这句代码:(你也可以查看该项目对应的该git仓库,其test目录是完全支持HMR功能的,你修改任何test目录下的代码都会重新加载):

if (module.hot) {
    module.hot.accept();
  }

关于HMR的相关内容你可以参考这篇文章。注意,我们的devServer是如下的配置:

  devServer: {
      publicPath: '/',
      open: true,
      port: 8080,
      contentBase: false,
      hot: true//强制开启HMR的
    }

此时你运行wcf --dev --devServer就会发现会自动打开页面,如果你不需要该功能可以通过自定义配置文件来覆盖open参数!

5.说明

(1)我们的webpack入口文件必须在package.json或者自定义的webpack配置文件中至少一处配置(多处配置会合并),如果两个地方都没有配置那么就会报错!

(2)我们的ExtractTextPlugin采用的是contentHash,而不是chunkHash,原因可以阅读Webpack中hash与chunkhash的区别,以及js与css的hash指纹解耦方案

6.新功能的添加

新功能的添加不再修改readme文件,其功能都会在changelog中说明。请查看该文件

7.可能出现的问题

(1)如果执行下面的命令不会自动打开浏览器,同时访问localhost:8080也无法访问

wcf --devServer

这时候请加上--dev,因为其会访问html内置的模板,其默认的目录在test目录下,因为这个例子是内置的HMR的例子,如果你不需要查看这个例子,请使用shell参数htmlTemplate参数来指定模板路径(依然需要添加--dev参数,因为html-webpack-plugin是开发插件)

(2)如果端口报错

 new RangeError('"port" argument must be >= 0 and < 65536');//设置的端口必须是数值类型

(3)必须安装webpack作为依赖,可以是全局安装也可以是局部安装

npm install webpack -g//或者npm install webpack --save -dev

(4)无法打开URL

此时请确保你的参数有--dev,因为如果没有这个参数那么我们不会添加HMR的插件,同时也不会添加HtmlWebpackPlugin,所以不会自动打开页面。

8.与atool-build的区别

(1)wcf集成了三种打包模式

上面已经说过了,我们的wcf集成了三种打包模式,而且功能是逐渐增强的。webpack模式只是打包一次,然后退出,和webpack自己的打包方式是一样的。webpack watch模式会自动监听文件是否发生变化,然后重新打包。webpack-dev-server模式天然支持了HMR,支持无刷新更新数据。具体你可以阅读文档

(2)很好的扩展性

atool-build提供一个mergeCustomConfig函数来合并用户自定义的配置与默认的配置,并将用户配置作为参数传入函数进行修改,但是当要修改的配置项很多的时候就比较麻烦。wcf自己也集成了很多loader对文件进行处理,但是很容易进行拓展,只要你配置自己的扩展文件就可以了,内部操作都会自动完成。你可以通过两种方式来配置:

cli模式:

wcf --dev --devServer --config "Your custom webpack config file path"
//此时会自动合并用户自定义的配置与默认配置,通过webpack-merge完成,而不用逐项修改

Nodejs模式:

const build = require("webpackcc/lib/build");
const program = {
    onlyCf : true,
    //不启动打包,只是获取最终配置信息
    cwd : process.cwd(),
    dev : true,
    //开发模式,不启动如UglifyJs等
    config :"Your custom webpack config file path"
  };
const finalConfig = build(program);
//得到最终的配置,想干嘛干嘛

通过nodejs模式,你可以获取webpack配置项用于其他地方。

下面给出一个完整的例子(假如下面给出的是我们自定义的配置文件):

module.exports = {
  entry:{
      'main': [
        'webpack-hot-middleware/client?path=http://' + host + ':' + port + '/__webpack_hmr',
        "bootstrap-webpack!./src/theme/bootstrap.config.js",
        './src/client.js'
      ]
  },
   output: {
      path: assetsPath,
      filename: '[name]-[hash].js',
      chunkFilename: '[name]-[chunkhash].js',
      publicPath: 'http://' + host + ':' + port + '/dist/'
    },
  plugins:[
    new webpack.DefinePlugin({
        __CLIENT__: true,
        __SERVER__: false,
        __DEVELOPMENT__: true,
        __DEVTOOLS__: true 
         // <-------- DISABLE redux-devtools HERE
      }),
     new webpack.IgnorePlugin(/webpack-stats\.json$/),
     webpackIsomorphicToolsPlugin.development()
  ],
   module:{
      rules:[
        { test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
        {
           test: webpackIsomorphicToolsPlugin.regular_expression('images'), 
           use: {
             loader: require.resolve("url-loader"),
             options:{}
           }
         },
           {
            test: /\.jsx$/,
            exclude :path.resolve("node_modules"),
            use: [{
              loader:require.resolve('babel-loader'),
              options:updateCombinedBabelConfig()
            }]
          },
            {
            test: /\.js$/,
            exclude :path.resolve("node_modules"),
            use: [{
              loader:require.resolve('babel-loader'),
              options:updateCombinedBabelConfig()
            }]
          }]
   }
}

注意:我们的wcf没有内置的entry,所以你这里配置的entry将会作为合并后的最终webpack配置的entry项。对于output来说,用户自定义的配置将会覆盖默认的配置(其他的也一样,除了module,plugins等)。对于plugin来说,我们会进行合并,此时不仅包含用户自定义的plugin,同时也包含内置的plugin。对于loader来说,如果有两个相同的loader,那么用户自定义的loader也会原样覆盖默认的loader。这样就很容易进行扩展。只要用户配置一个自定义配置文件的路径即可

(3)dedupe

atool-build并没有对我们的plugin和loader进行去重,这样可能导致同一个plugin被添加了两次,这就要求用户必须了解内置那些plugin,从而不去添加它。同时也会导致某一个js文件的loader也添加了两次,得到如下的内容:

 [ { test: { /\.jsx$/ [lastIndex]: 0 },
    exclude:
     { [Function: exclude]
       [length]: 1,
       [name]: 'exclude',
       [arguments]: null,
       [caller]: null,
       [prototype]: exclude { [constructor]: [Circular] } },
    use: [ { loader: 'babel-loader', options: {} }, [length]: 1 ] },
  { test: { /\.jsx$/ [lastIndex]: 0 },
  //对于jsx的loader又添加了一次
    exclude:
     { [Function: exclude]
       [length]: 1,
       [name]: 'exclude',
       [arguments]: null,
       [caller]: null,
       [prototype]: exclude { [constructor]: [Circular] } },
    use: [ { loader: 'after', options: {} }, [length]: 1 ] },
  [length]: 2 ]

这个问题你可以查看我给webpack-merge提出的issue。但是这些工作wcf已经做了,所以当你有两个相同的插件,或者两个相同的loader的情况下,都只会留下一个,并且用户自定义的优先级要高于默认配置的优先级。

(4)打包前进行钩子设置

如果在打包前,或者获取到最终配置之前,你要对最终配置做一个处理,比如删除某个plugin/loader,那么我们提供了一个钩子函数:

const program = {
    onlyCf : true,
    //此时不打包,只是为了获取最终配置用于nodejs
    cwd : process.cwd(),
    dev : true,
    //不启动压缩
    //下面这个hook用于去掉commonchunkplugin
    hook:function(webpackConfig){
         const commonchunkpluginIndex = webpackConfig.plugins.findIndex(plugin => {
           return plugin.constructor.name == "CommonsChunkPlugin"
         });
         webpackConfig.plugins.splice(commonchunkpluginIndex, 1);
         return webpackConfig;
    }
  };