webpack-config-zero
webpack.config 零配置定制化生成器
why?
- webpack 配置繁琐、复杂(蛋疼)
- webpack 很多项目在搭建脚手架时都是复制之前项目的
webpack.config.js
配置 - 如果有多套脚手架工程,当 webpack 的升级,配置优化和调整,这些脚手架需要逐一修改
How to use?
安装
webpack-config-zero
需要 webpack v4+ 以及 NodeJS v8+
npm i --save-dev webpack-config-zero
webpack 依赖
npm i --save-dev webpack webpack-cli webpack-dev-server
webpack loaders
npm i --save-dev @babel/core babel-loader style-loader css-loader node-sass sass-loader postcss-loader url-loader file-loader html-loader resolve-url-loader # 如果是 React 脚手架,为了正常启用热更新,你需要安装 react-hot-loader npm i --save-dev react-hot-loader@next # 如果是 Vue 脚手架,你需要安装额外的 loader npm i --save-dev vue-loader vue-template-compiler
webpack plugins
html-webpack-plugin with alpha version
webpack v4 使用了动态分割 chunk(splitChunks) 的功能,在多入口、多页面模式下,html-webpack-plugin 的现有版本没有很好的办法解决一个 html 只插入当前 entry 的依赖 chunks。默认状态下会把所有 chunks 插入,或者通过 opions.chunks 或者 options.excludeChunks 来解决,但 splitChunks 需要做大量的改动,且效果不是非常理想。现在, html-webpack-plugin@next 版本中似乎解决了这个问题。
npm i --save-dev html-webpack-plugin@next
plugins for build production
npm i --save-dev clean-webpack-plugin copy-webpack-plugin mini-css-extract-plugin uglifyjs-webpack-plugin optimize-css-assets-webpack-plugin inline-manifest-webpack-plugin
others
npm i --save-dev @babel/preset-env webpack-merge
安装推荐可选依赖
npm i --save-dev autoprefixer postcss-px2rem
TypeScript
安装 NPM 依赖包:
npm i --save-dev typescript ts-loader
在项目根目录中,新建文件 tsconfig.json
:
如果是 React 脚手架,需要增加 tsconfig.json
配置项:
{ "compilerOptions": { ...+ "jsx": "react" }, ...}
如果是 Vue 脚手架,需要在 src/
下新建声明文件 vue-shims.d.ts
:
declare
更多 TypeScript 配置,请参考:
目录规范
单页
.├── dist├── lib├── src│ ├── config│ │ └── public-path.js│ ├── containers│ │ ├── index.html│ │ └── index.js│ └── styles├── .babelrc└── webpack.config.js
多页
.├── dist├── lib├── src│ ├── config│ │ └── public-path.js│ ├── containers│ │ ├── About│ │ │ ├── about.scss│ │ │ ├── app.js│ │ │ ├── index.html│ │ │ └── index.js│ │ └── Home│ │ ├── app.js│ │ ├── home.scss│ │ ├── index.html│ │ └── index.js│ └── styles├── .babelrc└── webpack.config.js
配置
.babelrc
webpack.config.js
const zeroConfig = ;moduleexports = ;
package.json
Run
开发环境
npm start
生产构建
npm run build
windows 系统需要另外安装 cross-env 依赖包:
npm i --save-dev cross-env
修改 npm scripts:
"scripts": {- "build": "NODE_ENV=production webpack --progress --colors"+ "build": "cross-env NODE_ENV=production webpack --progress --colors"},
Options
属性 | 数据类型 | 默认值 | 说明 |
---|---|---|---|
input | String | 'src' | 源码目录 |
output | String | 'dist' | 打包输出目录 |
include | Object | 需要额外执行 loader 的路径。某些 node_modules 下的 npm 包(比如本人),是没有进行过(比如 ES6, SASS 等)转换的 |
|
spa | Boolean | true | 单/多页选项。entry、代码分离、html-webpack-plugins 都会根据该选项来做不同的处理 |
cssModules | Boolean | true | 开启 cssModules 。如果为 true ,src/styles 下默认会做 global 处理,不需要额外声明 :global |
containers | String | 'containers' | 页面容器目录,位于 src 下 |
runtimePublicPath | String | ' /' | webpack 的运行时 publicPath 路径,该值将会注入到 process.env.RUNTIME_PUBLIC_PATH 变量,通常用于异步 chunk。注意:需要在入口模块处单独导入,见下方示例 |
copyPathname | String | 'lib' | 第三方非模块文件目录 |
multipageHome | String | 'home' | spa 为 false 时,src/containers 下将哪个页面容器作为主入口 |
customizeHtmlWebpackPlugins | Function | null | 自定义 html-webpack-plugin 模版,该方法需要返回含有 html-webpack-plugin 实例的数组 |
view | String | 'react' | 'vue' | 'pure' | 默认会自动检测项目根目录下 package.json 中安装的 view 依赖框架(React 或 Vue),如果 2 者都没有,默认设置为 'pure',你也可以手动修改 |
runtimePublicPath:
// public-path.js__webpack_public_path__ = processenvRUNTIME_PUBLIC_PATH; // entry.js// import other modules
参见:webpack 官方指南
include
通过 options
传入的参数会和默认值合并:
属性 | 数据类型 | 默认值 | 说明 |
---|---|---|---|
js | Array | [ '/src' ] | 需要 babel-loader 编译的目录路径,支持:*.js, *.jsx |
css | Array | [ '/src' ] | 需要 sass-loader 编译的目录路径,支持:*.css, *.scss |
cssModules | Object | { global: [ '/src/styles' ], local: [ '/src' ] } | 需要 css-loader 的 CSS-MODULES 编译的目录路径,options.cssModules 为 true 时有效,支持:*.css, *.scss |
res | Array | [ '/src' ] | 需要 file-loader 处理的目录路径,支持:*.jpg, *.png, *.gif, *.svg, *.eot, *.woff, *.ttf, *.svg, *.mp3 |
默认配置无法满足怎么办?
安装 webpack-merge
,然后扩展默认配置:
const zeroConfig = ;const webpackMerge = ; moduleexports = ;
根据不同环境扩展默认配置:
let config = ; if processenvNODE_ENV !== 'production' config = ; else config = ; moduleexports = config;