1.1.2 • Published 9 months ago

create-webpack-next v1.1.2

Weekly downloads
-
License
MIT
Repository
-
Last release
9 months ago

create-webpack-next

Fork me on Gitee

version dt

创建次世代的 webpack 应用程序开发环境。

该指令将自动创建一个初始化的 webpack 项目环境,并添加所需必要的库。

开发环境主要集成:

  • webpackwebpack-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
  • react, react-dom
  • windicss
  • postcss 插件:postcss-preset-env, autoprefixer, postcss-flexbugs-fixes
  • ts-node 可直接执行 ts
  • eslint
    • @typescript-eslint/parser, @typescript-eslint/eslint-plugin
    • eslint-plugin-react, eslint-plugin-react-hooks

具体版本,请参考 dependencies.ts 文件。

img.png

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 增加第二个参数,以传递更多的插件
  • 增加 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.tsximport '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,具体而言:
      1. 工程配置化,可随着项目发展对 webpack 及相关部分进行更深入的定制。
      2. 学习与研究,基于 webpack 环境,对各种插件和 loader 的尝试与定制,以及打包策略的调整等。
  • 项目建立的时间点不同,导致依赖工具链环境差异。

    • create-react-app 建立时间早,遵循其基础立场,而且存在诸多不合理的地方,并且很难在短期做更大的改进:
      1. 使用 babel-loader 对 js/ts 进行转译;
      2. 运行时加入了诸如 eslint-webpack-plugin react-dev-utils/ForkTsCheckerWarningWebpackPlugin 等语法检查工具,这种做法本身就很值得商榷,并不是一个大中型项目工程值得参考的做法。个人更推荐在 per-commit 阶段进行语法检查(诸如 husky 或如 JetBrains IDE 等)。
      3. 官方还整合一些其他的插件,并不见得其必要性,更不体现其能突出 react 的何种特性。
    • create-webpack-next

      1. 使用 swc-loader,官方号称:SWC is 20x faster than Babel on a single thread and 70x faster on four cores.
      2. eslint 只作为项目环境配置,而非运行时使用。
      3. 所加入的配置和插件,立足于 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-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 增加第二个参数,以传递更多的插件
  • 增加 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 包,如果需要,请自行安装。
1.1.2

9 months ago

1.1.1

1 year ago

1.1.0

1 year ago

1.0.9

1 year ago

1.0.8

1 year ago

1.0.7

1 year ago

1.0.6

2 years ago

1.0.5

2 years ago

1.0.4

2 years ago

1.0.3

2 years ago

1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago