create-webpack-next
v1.1.2
Published
Create webpack application within next-generation libraries.
Downloads
7
Maintainers
Readme
create-webpack-next
创建次世代的 webpack 应用程序开发环境。
该指令将自动创建一个初始化的 webpack 项目环境,并添加所需必要的库。
开发环境主要集成:
webpack
,webpack-cli
,webpack-dev-server
- loaders:
css-loader
,style-loader
,url-loader
,file-loader
,@svgr/webpack
,postcss-loader
,swc-loader
(JS/TS 转译加载器,替换 babel-loader / ts-loader) - plugins:
terser-webpack-plugin
,css-minimizer-webpack-plugin
,mini-css-extract-plugin
,html-webpack-plugin
,react-dev-utils
,@pmmmwh/react-refresh-webpack-plugin
,dotenv-webpack
,react-refresh
(保留,有兴趣可以试试),webpack-manifest-plugin
- loaders:
react
,react-dom
windicss
- postcss 插件:
postcss-preset-env
,autoprefixer
,postcss-flexbugs-fixes
ts-node
可直接执行 tseslint
@typescript-eslint/parser
,@typescript-eslint/eslint-plugin
eslint-plugin-react
,eslint-plugin-react-hooks
具体版本,请参考 dependencies.ts 文件。
dev server 启动界面截图
版本特性说明
1.0.x
最后版本到 1.0.9
,旧版本。
1.1.x
- 调整创建的项目结构(根据实际项目结构调整)
- 调整部分文件命名
- 分离出 app 目录(分离 App 组件和 AppService 类)
- 添加 components/hooks 目录
- webpack 部分
- webpack
dotenv-webpack
导入环境变量统一在import.meta.env.
下,和 Vite 对齐 webpack.plugins.js
增加第二个参数,以传递更多的插件
- webpack
- 增加 Vite 支持
- Vite 插件、功能,与 webpack 对齐
命令行参数
npx create-webpack-next <name>
# 使用帮助和查看版本号
npx create-webpack-next --help
npx create-webpack-next --version
# 更新新版本
# 如果之前通过 npx 指令使用过
npx create-webpack-next@latest --help
npx create-webpack-next <name> -p yarn
npx create-webpack-next <name> -p pnpm -r 17
--react|-r
指定 React 版本号,默认为 18
。
--package-manager|-p
默认为 npm
,可选 npm
yarn
pnpm
,选择本地 node 包管理器。
--install|-i
默认为 true
是否自动安装依赖包,根据指定的 --package-manager|-p
安装依赖库。
--vite
默认为 false
是否同时启用 Vite (推荐开发环境使用)。
针对 swc-loader 和 CSS in JS 的说明
目前市面主流的 CSS in JS 库,大体依赖于 babel 进行处理。
基于 swc-loader 环境,项目中仍旧需要添加以下的 babel 库:
yarn add @babel/core @babel/preset-env @babel/preset-react @compiled/babel-plugin -D
我针对 linaria , @compiled, vanilla-extract, astroturf 这四个能提供静态 CSS 分离的库,做了本地测试,都能在 swc-loader 环境下跑通(还包括 emotion, goober, stitches 等)。
如 @compiled:
webpack.config.js 文件
{
test : /\.(ts|tsx)$/,
exclude: /(node_modules|bower_components)/,
use : [
{ loader: 'swc-loader' },
{
loader: '@compiled/webpack-loader',
options: {
extract: false,
importReact: false,
extensions: ['.js', '.jsx', '.ts', '.tsx']
},
},
]
}
.babelrc 文件
{
"presets": [
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript"
],
"plugins": [
[
"@compiled/babel-plugin",
{
"importReact": true,
"cache": true
}
]
]
}
目前 Next.js 也是基于 webpack + swc-loader 进行转译的,如果配置 CSS in JS 的环境有问题,可以去翻翻 Next.js 的 examples 库。
不要 Windi CSS ?
直接在入口文件 src/index.tsx
把 import 'windi.css';
删除掉即可。
路径 resolve 说明
目前默认已经添加了 tsconfig-paths-webpack-plugin
,只要在 tsconfig.json 中添加了 paths ,webpack 环境下自动加载,无需额外配置。
如果要在脱离了 webpack 环境也能生效,则仍需再安装 tsconfig-paths
。
其次,也可以使用 pnpm 以 workspace 方式来管理项目:
package.json
{
"dependencies": {
"your-lib": "workspace:*"
}
}
然后记得 pnpm update
or pnpm update -r
or pnpm install
也可。
或者在子项目下:
pnpm add your-lib@workspace:*
语法和 remote add 一样。
单元测试例子
本来想加上单元测试的依赖的代码的,但想想其实也没必要。现在 React 周边都很成熟了,没必要非要 jest 了,mocha 更好(跑的更快)。断言库也可以自己选,比如我喜欢用 chai。
组件测试
pnpm add react-test-renderer @types/react-test-renderer -D
import * as React from 'react';
import { create } from 'react-test-renderer';
import { expect } from 'chai';
import { Flex } from './Flex';
let root: HTMLElement;
describe('Flex test in react-test-runner', function () {
it('should align items center', () => {
const { props } = create(<div className="ok"/>).toTree();
expect(props).to.have.property('className');
expect(props.className).to.contain('ok');
});
});
Hooks 测试
pnpm add @testing-library/react-hooks -D
import { expect } from 'chai';
import * as React from 'react';
import { useState, useCallback } from 'react';
import { renderHook, act } from '@testing-library/react-hooks';
function useCounter() {
const [count, setCount] = useState(0);
const increment = useCallback(() => setCount((x) => x + 1), []);
return { count, increment };
}
describe('hook test in @testing-library/react-hooks', function () {
it('should increment counter', () => {
const { result } = renderHook(() => useCounter());
act(() => result.current.increment());
expect(result.current.count).to.eql(1);
});
});
为何重复造轮子(vs create-react-app)
首先必须承认,本项目的 webpack.config.js 有参考自 create-react-app。
其次,和 create-react-app 比较:
- 立场差异:
- create-react-app 是 react 官方(facebook)出品,他创建的项目,立足于突出 react 的特点。故而将 webpack/postcss 等配置进行隐藏,集中突显立刻上手体验 react 的明确性。
- create-webpack-next 立足于创建可定制的 webpack 环境,不局限于 react,具体而言:
- 工程配置化,可随着项目发展对 webpack 及相关部分进行更深入的定制。
- 学习与研究,基于 webpack 环境,对各种插件和 loader 的尝试与定制,以及打包策略的调整等。
- 项目建立的时间点不同,导致依赖工具链环境差异。
- create-react-app 建立时间早,遵循其基础立场,而且存在诸多不合理的地方,并且很难在短期做更大的改进:
- 使用 babel-loader 对 js/ts 进行转译;
- 运行时加入了诸如
eslint-webpack-plugin
react-dev-utils/ForkTsCheckerWarningWebpackPlugin
等语法检查工具,这种做法本身就很值得商榷,并不是一个大中型项目工程值得参考的做法。个人更推荐在 per-commit 阶段进行语法检查(诸如 husky 或如 JetBrains IDE 等)。 - 官方还整合一些其他的插件,并不见得其必要性,更不体现其能突出 react 的何种特性。
- create-webpack-next
使用 swc-loader,官方号称:SWC is 20x faster than Babel on a single thread and 70x faster on four cores.
eslint 只作为项目环境配置,而非运行时使用。
所加入的配置和插件,立足于
next generation
,故而连 less/sass/stylus 这种 css 预处理器也不考虑。次世代的 CSS
藉由 JS 运行时的动态 Statement 构建出 CSS(或由编译器预处理,或实时动态 generate,也即 CSS in JS)
- 预处理型:
linaria
,@compiled
,vanilla-extract
,astroturf
等,支持静态 CSS 提取,生成 css var,支持拆分原子 CSS(或可)。 - 实时生成型:
emotion
,styled-components
,goober
,stitches
等 - 工具辅助型(可以在任意 CSS in JS 种使用):
polished
,styled-system
等 - 异形:
react-native
直接生成所需的 styles,看似怪异,但却会上瘾。
- 预处理型:
- create-react-app 建立时间早,遵循其基础立场,而且存在诸多不合理的地方,并且很难在短期做更大的改进:
再次,无论 create-react-app 或 create-webpack-next 都旨在为用户提供开箱即用、可立刻体验式的 react/webpack 项目创建脚手架,都为 JS/TS/CSS/CSS Modules 等最基础的 web 前端开发环境提供处理支持。
更新记录
1.1.1
- 增加
prettier
1.1.0
- 调整创建的项目结构(根据实际项目结构调整)
- 调整部分文件命名
- 分离出 app 目录(分离 App 组件和 AppService 类)
- 添加 components/hooks 目录
- webpack 部分
- webpack
dotenv-webpack
导入环境变量统一在import.meta.env.
下,和 Vite 对齐 webpack.plugins.js
增加第二个参数,以传递更多的插件
- webpack
- 增加 Vite 支持
- Vite 插件、功能,与 webpack 对齐
1.0.8 / 1.0.9
- 修正默认 react 18 未生效的问题
摆乌龙,状态不好,忘记 build 了
1.0.7
- align 依赖库的最新版本
- react
-r
未指定时,默认为18
- 去除
chokidar
- fix React 18 的 hot-reload 机制,修改模板
.swcrc
内容。
1.0.6
- 增加
--react|-r
参数,默认为17
1.0.5
- 拆分 webpack.config.js 文件内容到
config/webpack.*.js
中 - 创建真实世界的应用程序环境
- 创建 AppService 类,管理全局应用程序环境;
styles/index.css
全局样式pages
对应页面入口pages/Home.tsx
pages/Home.module.css
首页示例- 样式从标签上转移到 css 中,使用
@apply
的 windi-css 语法
1.0.4
- 针对 swc-loader 优化
@pmmmwh/react-refresh-webpack-plugin
配置,参考; - 增加
tsconfig-paths-webpack-plugin
插件,tsconfig paths 可自动加入 webpack resolve alias (无需手动配置); - 移除
react-dev-utils/ModuleScopePlugin
限制,去掉 tsconfig rootDir 配置; - 调整生成的文件名,图片使用 [contenthash:8],js 和 css 的 chunk 文件使用 [fullhash:8] ,主文件不带 hash。
- 使用 windi css 替换 tailwind css
- 增加 webpack-manifest-plugin 插件
1.0.3
- 调整 svgr 的配置,改为导入 svg 文件自动生成组件(React.memo)。
webpack.config.js.ejs
增加 image-webpack-loader 的配置,但默认不开启(被注释掉),也不会添加 image-webpack-loader 包,如果需要,请自行安装。