Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug Report] 使用 babel-plugin-import 按需 css 导入失败 #1842

Closed
1 task done
7kms opened this issue Jul 20, 2021 · 2 comments · Fixed by #1843
Closed
1 task done

[Bug Report] 使用 babel-plugin-import 按需 css 导入失败 #1842

7kms opened this issue Jul 20, 2021 · 2 comments · Fixed by #1843

Comments

@7kms
Copy link
Contributor

7kms commented Jul 20, 2021

  • I have searched the issues of this repository and believe that this is not a duplicate.

Steps to reproduce

  1. 按照文档配置babel-plugin-import
  2. 开发环境即可复现

What is expected?

能正确导入css

What is actually happening?

css丢失

Package

@formily/[email protected]


@janryWang
Copy link
Collaborator

复现链接发一下

@7kms
Copy link
Contributor Author

7kms commented Jul 20, 2021

复现步骤

  1. webpack.config中按需配置了babel-plugin-import
{
            test: /\.(js|mjs|jsx|ts|tsx)$/,
            include: [
              resolve(cwd, 'src')
            ],
            loader: 'babel-loader',
            options: {
              babelrc: false,
              configFile: false,
              presets: [
                '@babel/preset-env',
                '@babel/preset-react',
                '@babel/preset-typescript',
              ],
              plugins: [
                [
                  "import",
                  {
                    "libraryName": "antd",
                    "libraryDirectory": "lib",
                    "style": true
                  },
                  'antd'
                ],
                [
                  "import",
                  {
                    "libraryName": "@formily/antd",
                    "libraryDirectory": "lib",
                    "style": true
                  },
                  '@formily/antd'
                ]
              ]
            }
          }
  1. 在业务代码中使用formily
import React from "react";
import { createForm } from "@formily/core";
import { createSchemaField } from "@formily/react";
import { Form, FormItem, Input, Password, Submit } from "@formily/antd";
import { Tabs, Card, Modal, Alert, BackTop } from "antd";

这个webpack配置最终编译出来的结果如下:

/* harmony import */ var antd_lib_card_style__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! antd/lib/card/style */ "./node_modules/antd/lib/card/style/index.js");
/* harmony import */ var antd_lib_card_style__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(antd_lib_card_style__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var antd_lib_card__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! antd/lib/card */ "./node_modules/antd/lib/card/index.js");
/* harmony import */ var antd_lib_tabs_style__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! antd/lib/tabs/style */ "./node_modules/antd/lib/tabs/style/index.js");
/* harmony import */ var antd_lib_tabs_style__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(antd_lib_tabs_style__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var antd_lib_tabs__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! antd/lib/tabs */ "./node_modules/antd/lib/tabs/index.js");


// -----------分割线-------------------



/* harmony import */ var _formily_antd_lib_form__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @formily/antd/lib/form */ "./node_modules/@formily/antd/lib/form/index.js");
/* harmony import */ var _formily_antd_lib_form__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(_formily_antd_lib_form__WEBPACK_IMPORTED_MODULE_12__);
/* harmony import */ var _formily_antd_lib_submit__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @formily/antd/lib/submit */ "./node_modules/@formily/antd/lib/submit/index.js");
/* harmony import */ var _formily_antd_lib_submit__WEBPACK_IMPORTED_MODULE_13___default = /*#__PURE__*/__webpack_require__.n(_formily_antd_lib_submit__WEBPACK_IMPORTED_MODULE_13__);
/* harmony import */ var _formily_antd_lib_password__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @formily/antd/lib/password */ "./node_modules/@formily/antd/lib/password/index.js");
/* harmony import */ var _formily_antd_lib_password__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(_formily_antd_lib_password__WEBPACK_IMPORTED_MODULE_8__);
/* harmony import */ var _formily_antd_lib_input__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @formily/antd/lib/input */ "./node_modules/@formily/antd/lib/input/index.js");
/* harmony import */ var _formily_antd_lib_input__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_formily_antd_lib_input__WEBPACK_IMPORTED_MODULE_7__);
/* harmony import */ var _formily_antd_lib_form_item__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @formily/antd/lib/form-item */ "./node_modules/@formily/antd/lib/form-item/index.js");
/* harmony import */ var _formily_antd_lib_form_item__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_formily_antd_lib_form_item__WEBPACK_IMPORTED_MODULE_6__);

上述代码片段中, 可以发现分割线以前的是antd相关引入, 分割线以后的是formily相关引入. antd可以按需引入样式, 但是@formily/antd并没有对应的css引入.

此时页面确实有样式问题

image

问题排查

  1. 根据经验, 可以大致定位是webpack的tree shaking特性导致
  2. tree shaking的实现与package.json中配置的sideEffects相关, 所以对比了antd@formily/antdpackage.json中相关的配置, 发现@formily/antd确实有点问题
"sideEffects": [
   "dist/*",
   "es/**/style/*",
   "lib/**/style/*",
   "*.less"
 ]

其中lib/**/style/*正好能匹配其代码结构

├── lib
│   ├── affix
│   │   ├── index.d.ts
│   │   ├── index.js
│   │   ├── style
│   │   │   ├── css.js
│   │   │   ├── index.css
│   │   │   ├── index.d.ts
│   │   │   ├── index.js
│   │   │   └── index.less
│   │   ├── utils.d.ts
│   │   └── utils.js
  • @formily/antd中的配置是
"sideEffects": [
    "dist/*",
    "esm/*.js",
    "lib/*.js",
    "src/*.ts",
    "*.less"
  ]

所有条件都无法命中目录结构中的*.style.js, 目录结构如下:

├── lib
│   ├── array-base
│   │   ├── index.d.ts
│   │   ├── index.js
│   │   ├── index.js.map
│   │   ├── style.d.ts
│   │   ├── style.js
│   │   ├── style.js.map
│   │   └── style.less

babel-plugin-import按需引入之后, 由于webpacksideEffects没有命中style.js, 所以style相关的引入代码被tree shaking掉了

临时解决方案

  1. 修改webpack.config配置, 显示设置babel-loader所在rule中的sideEffects=true
{
sideEffects: true,  // 在这里加一个显示的配置
            test: /\.(js|mjs|jsx|ts|tsx)$/,
            include: [
              resolve(cwd, 'src')
            ],
            loader: 'babel-loader',
            options: {
              babelrc: false,
              configFile: false,
              presets: [
                '@babel/preset-env',
                '@babel/preset-react',
                '@babel/preset-typescript',
              ],
              plugins: [
                [
                  "import",
                  {
                    "libraryName": "antd",
                    "libraryDirectory": "lib",
                    "style": true
                  },
                  'antd'
                ],
                [
                  "import",
                  {
                    "libraryName": "@formily/antd",
                    "libraryDirectory": "lib",
                    "style": true
                  },
                  '@formily/antd'
                ]
              ]
            }
          }

这种方案一刀切, 全部都有副作用, 会错杀了别的需要tree shaking的代码

  1. 修改@formily/antd/package.json中的sideEffects, 使其能够匹配style.js

以上2种方式最后都能达到目的, 编译后的代码如下:

/* harmony import */ var antd_lib_card_style__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! antd/lib/card/style */ "./node_modules/antd/lib/card/style/index.js");
/* harmony import */ var antd_lib_card_style__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(antd_lib_card_style__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var antd_lib_card__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! antd/lib/card */ "./node_modules/antd/lib/card/index.js");
/* harmony import */ var antd_lib_tabs_style__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! antd/lib/tabs/style */ "./node_modules/antd/lib/tabs/style/index.js");
/* harmony import */ var antd_lib_tabs_style__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(antd_lib_tabs_style__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var antd_lib_tabs__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! antd/lib/tabs */ "./node_modules/antd/lib/tabs/index.js");



// -----------分割线-------------------



/* harmony import */ var _formily_antd_lib_form_style__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @formily/antd/lib/form/style */ "./node_modules/@formily/antd/lib/form/style.js");
/* harmony import */ var _formily_antd_lib_form__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @formily/antd/lib/form */ "./node_modules/@formily/antd/lib/form/index.js");
/* harmony import */ var _formily_antd_lib_form__WEBPACK_IMPORTED_MODULE_16___default = /*#__PURE__*/__webpack_require__.n(_formily_antd_lib_form__WEBPACK_IMPORTED_MODULE_16__);
/* harmony import */ var _formily_antd_lib_submit_style__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @formily/antd/lib/submit/style */ "./node_modules/@formily/antd/lib/submit/style.js");
/* harmony import */ var _formily_antd_lib_submit__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @formily/antd/lib/submit */ "./node_modules/@formily/antd/lib/submit/index.js");
/* harmony import */ var _formily_antd_lib_submit__WEBPACK_IMPORTED_MODULE_17___default = /*#__PURE__*/__webpack_require__.n(_formily_antd_lib_submit__WEBPACK_IMPORTED_MODULE_17__);
/* harmony import */ var _formily_antd_lib_password_style__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @formily/antd/lib/password/style */ "./node_modules/@formily/antd/lib/password/style.js");
/* harmony import */ var _formily_antd_lib_password__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @formily/antd/lib/password */ "./node_modules/@formily/antd/lib/password/index.js");
/* harmony import */ var _formily_antd_lib_password__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(_formily_antd_lib_password__WEBPACK_IMPORTED_MODULE_12__);
/* harmony import */ var _formily_antd_lib_input_style__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @formily/antd/lib/input/style */ "./node_modules/@formily/antd/lib/input/style.js");
/* harmony import */ var _formily_antd_lib_input__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @formily/antd/lib/input */ "./node_modules/@formily/antd/lib/input/index.js");

可以看到分割线之后, 与@formily/antd相关的样式成功引入了, 没有被tree shaking.

这时候页面显示也正常了

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants