├── .eslintignore
├── src
├── index.js
└── core.js
├── .npmignore
├── .travis.yml
├── .gitignore
├── test
├── fixtures
│ ├── execute-direct
│ │ ├── actual.js
│ │ └── expected.js
│ ├── as-arguments
│ │ ├── actual.js
│ │ └── expected.js
│ ├── execute-member
│ │ ├── actual.js
│ │ └── expected.js
│ ├── multiple-words
│ │ ├── actual.js
│ │ └── expected.js
│ ├── variable-declarator
│ │ ├── actual.js
│ │ └── expected.js
│ ├── camel-to-dash-option
│ │ ├── actual.js
│ │ └── expected.js
│ ├── array
│ │ ├── actual.js
│ │ └── expected.js
│ ├── property
│ │ ├── actual.js
│ │ └── expected.js
│ ├── import-theme
│ │ ├── actual.js
│ │ └── expected.js
│ ├── import-all-css
│ │ ├── actual.js
│ │ └── expected.js
│ ├── import-module
│ │ ├── actual.js
│ │ └── expected.js
│ ├── import-theme-custom
│ │ ├── actual.js
│ │ └── expected.js
│ ├── import-theme-custom-path
│ │ ├── actual.js
│ │ └── expected.js
│ ├── independent-theme-package
│ │ ├── actual.js
│ │ └── expected.js
│ ├── react-element
│ │ ├── actual.js
│ │ └── expected.js
│ ├── independent-theme-package-mixin
│ │ ├── actual.js
│ │ └── expected.js
│ ├── independent-theme-package-custom
│ │ ├── actual.js
│ │ └── expected.js
│ ├── assignment-expression
│ │ ├── actual.js
│ │ └── expected.js
│ ├── specifier-alias
│ │ ├── actual.js
│ │ └── expected.js
│ ├── import-theme-all-compo
│ │ ├── actual.js
│ │ └── expected.js
│ ├── import-css
│ │ ├── actual.js
│ │ └── expected.js
│ ├── custom-css-filename
│ │ ├── actual.js
│ │ └── expected.js
│ ├── conditions
│ │ ├── actual.js
│ │ └── expected.js
│ └── multiple-module
│ │ ├── actual.js
│ │ └── expected.js
└── index-test.js
├── .eslintrc
├── package.json
└── README.md
/.eslintignore:
--------------------------------------------------------------------------------
1 | **/*/__tests__
2 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require('./core')('element-ui');
2 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .idea
2 | tmp
3 | node_modules
4 | coverage
5 | __tests__
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | node_js:
4 | - "4"
5 | - "5"
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | tmp
3 | node_modules
4 | coverage
5 | lib
6 | .DS_Store
7 |
--------------------------------------------------------------------------------
/test/fixtures/execute-direct/actual.js:
--------------------------------------------------------------------------------
1 | import { message } from 'element-ui';
2 |
3 | message('xxx');
4 |
--------------------------------------------------------------------------------
/test/fixtures/as-arguments/actual.js:
--------------------------------------------------------------------------------
1 | import { Modal } from 'element-ui';
2 | const _Modal = bind({})(Modal);
3 |
--------------------------------------------------------------------------------
/test/fixtures/execute-member/actual.js:
--------------------------------------------------------------------------------
1 | import { message } from 'element-ui';
2 |
3 | message.success('xxx');
4 |
--------------------------------------------------------------------------------
/test/fixtures/multiple-words/actual.js:
--------------------------------------------------------------------------------
1 | import { InputNumber } from 'element-ui';
2 |
3 | ;
4 |
--------------------------------------------------------------------------------
/test/fixtures/variable-declarator/actual.js:
--------------------------------------------------------------------------------
1 | import { Button } from 'element-ui';
2 |
3 | const a = Button;
4 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "eslint-config-airbnb/base",
3 | "rules": {
4 | "no-console": [0]
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/test/fixtures/camel-to-dash-option/actual.js:
--------------------------------------------------------------------------------
1 | import { inputNumber } from 'antd';
2 |
3 | console.log(inputNumber);
4 |
--------------------------------------------------------------------------------
/test/fixtures/array/actual.js:
--------------------------------------------------------------------------------
1 | import { Button } from 'element-ui';
2 |
3 | new Vue({
4 | components: [Button]
5 | });
6 |
--------------------------------------------------------------------------------
/test/fixtures/property/actual.js:
--------------------------------------------------------------------------------
1 | import { Button } from 'element-ui';
2 |
3 | ReactDOM.render(
);
4 |
--------------------------------------------------------------------------------
/test/fixtures/import-theme/actual.js:
--------------------------------------------------------------------------------
1 | import { Button, Alert } from 'element-ui';
2 |
3 | console.log(Button);
4 | console.log(Alert);
5 |
--------------------------------------------------------------------------------
/test/fixtures/import-all-css/actual.js:
--------------------------------------------------------------------------------
1 | import Element from 'element-ui';
2 |
3 | console.log(Element.Button);
4 | console.log(Element);
5 |
--------------------------------------------------------------------------------
/test/fixtures/import-module/actual.js:
--------------------------------------------------------------------------------
1 | import Element from 'element-ui';
2 |
3 | console.log(Element.Button);
4 | console.log(Element);
5 |
--------------------------------------------------------------------------------
/test/fixtures/import-theme-custom/actual.js:
--------------------------------------------------------------------------------
1 | import { Button, Alert } from 'element-ui4';
2 |
3 | console.log(Button);
4 | console.log(Alert);
5 |
--------------------------------------------------------------------------------
/test/fixtures/import-theme-custom-path/actual.js:
--------------------------------------------------------------------------------
1 | import { Button, Alert } from 'element-ui5';
2 |
3 | console.log(Button);
4 | console.log(Alert);
5 |
--------------------------------------------------------------------------------
/test/fixtures/independent-theme-package/actual.js:
--------------------------------------------------------------------------------
1 | import { Button, Alert } from 'element-ui3';
2 |
3 | console.log(Button);
4 | console.log(Alert);
5 |
--------------------------------------------------------------------------------
/test/fixtures/react-element/actual.js:
--------------------------------------------------------------------------------
1 | import { Button } from 'element-ui';
2 |
3 | ReactDOM.render(
4 |
5 |
);
6 |
--------------------------------------------------------------------------------
/test/fixtures/independent-theme-package-mixin/actual.js:
--------------------------------------------------------------------------------
1 | import { Button, Alert } from 'element-ui7';
2 |
3 | console.log(Button);
4 | console.log(Alert);
5 |
--------------------------------------------------------------------------------
/test/fixtures/independent-theme-package-custom/actual.js:
--------------------------------------------------------------------------------
1 | import { Button, Alert } from 'element-ui6';
2 |
3 | console.log(Button);
4 | console.log(Alert);
5 |
--------------------------------------------------------------------------------
/test/fixtures/assignment-expression/actual.js:
--------------------------------------------------------------------------------
1 | import { MessageBox } from 'element-ui';
2 | import Vue from 'vue';
3 |
4 | Vue.$prototype.$message = MessageBox;
5 |
--------------------------------------------------------------------------------
/test/fixtures/specifier-alias/actual.js:
--------------------------------------------------------------------------------
1 | import { Button as Button1 } from 'element-ui';
2 |
3 | ReactDOM.render(
4 | xxxx
5 |
);
6 |
--------------------------------------------------------------------------------
/test/fixtures/import-theme-all-compo/actual.js:
--------------------------------------------------------------------------------
1 | import Components from 'element-ui2';
2 | import { Button, Alert } from 'element-ui2';
3 |
4 | console.log(Components);
5 | console.log(Button, Alert);
6 |
--------------------------------------------------------------------------------
/test/fixtures/import-css/actual.js:
--------------------------------------------------------------------------------
1 | import { message } from 'element-ui';
2 | import { Button } from 'element-ui';
3 |
4 | message('xxx');
5 | ReactDOM.render(
6 |
7 |
);
8 |
--------------------------------------------------------------------------------
/test/fixtures/custom-css-filename/actual.js:
--------------------------------------------------------------------------------
1 | import { message } from 'element-ui';
2 | import { Button } from 'element-ui';
3 |
4 | message('xxx');
5 | ReactDOM.render(
6 |
7 |
);
8 |
--------------------------------------------------------------------------------
/test/fixtures/conditions/actual.js:
--------------------------------------------------------------------------------
1 | import { Select } from 'element-ui';
2 |
3 | if (a === Select) {}
4 | if (Select) {}
5 |
6 | Select ? 'a' : 'b';
7 | a ? Select : 2;
8 |
9 | Select || 'a';
10 | a || Select;
11 |
--------------------------------------------------------------------------------
/test/fixtures/execute-direct/expected.js:
--------------------------------------------------------------------------------
1 | require("element-ui/lib/message/style.css");
2 |
3 | var _message = _interopRequireDefault(require("element-ui/lib/message")).default;
4 |
5 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6 |
7 | _message('xxx');
8 |
--------------------------------------------------------------------------------
/test/fixtures/variable-declarator/expected.js:
--------------------------------------------------------------------------------
1 | require("element-ui/lib/button/style.css");
2 |
3 | var _Button = _interopRequireDefault(require("element-ui/lib/button")).default;
4 |
5 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6 |
7 | var a = _Button;
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/as-arguments/expected.js:
--------------------------------------------------------------------------------
1 | require("element-ui/lib/modal/style.css");
2 |
3 | var _Modal2 = _interopRequireDefault(require("element-ui/lib/modal")).default;
4 |
5 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6 |
7 | var _Modal = bind({})(_Modal2);
8 |
--------------------------------------------------------------------------------
/test/fixtures/execute-member/expected.js:
--------------------------------------------------------------------------------
1 | require("element-ui/lib/message/style.css");
2 |
3 | var _message = _interopRequireDefault(require("element-ui/lib/message")).default;
4 |
5 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6 |
7 | _message.success('xxx');
8 |
--------------------------------------------------------------------------------
/test/fixtures/camel-to-dash-option/expected.js:
--------------------------------------------------------------------------------
1 | require("antd/lib/inputNumber/style.css");
2 |
3 | var _inputNumber = _interopRequireDefault(require("antd/lib/inputNumber")).default;
4 |
5 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6 |
7 | console.log(_inputNumber);
8 |
--------------------------------------------------------------------------------
/test/fixtures/array/expected.js:
--------------------------------------------------------------------------------
1 | require("element-ui/lib/button/style.css");
2 |
3 | var _Button = _interopRequireDefault(require("element-ui/lib/button")).default;
4 |
5 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6 |
7 | new Vue({
8 | components: [_Button]
9 | });
10 |
--------------------------------------------------------------------------------
/test/fixtures/import-all-css/expected.js:
--------------------------------------------------------------------------------
1 | require("element-ui/lib/style.css");
2 |
3 | var _Element = _interopRequireDefault(require("element-ui/lib")).default;
4 |
5 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6 |
7 | console.log(_Element.Button);
8 | console.log(_Element);
9 |
--------------------------------------------------------------------------------
/test/fixtures/import-module/expected.js:
--------------------------------------------------------------------------------
1 | require("element-ui/lib/abc/style.css");
2 |
3 | var _Element = _interopRequireDefault(require("element-ui/lib/abc")).default;
4 |
5 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6 |
7 | console.log(_Element.Button);
8 | console.log(_Element);
9 |
--------------------------------------------------------------------------------
/test/fixtures/multiple-module/actual.js:
--------------------------------------------------------------------------------
1 | import { message } from 'antd';
2 | import { Button } from 'antd';
3 | import { Alert2 } from 'antd';
4 | import { Alert } from 'test-module';
5 |
6 | message('xxx');
7 | ReactDOM.render(
8 |
9 |
xxxx
10 |
xxx
11 |
);
12 |
--------------------------------------------------------------------------------
/test/fixtures/multiple-words/expected.js:
--------------------------------------------------------------------------------
1 | require("element-ui/lib/input-number/style.css");
2 |
3 | var _InputNumber = _interopRequireDefault(require("element-ui/lib/input-number")).default;
4 |
5 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6 |
7 | React.createElement(_InputNumber, null);
8 |
--------------------------------------------------------------------------------
/test/fixtures/property/expected.js:
--------------------------------------------------------------------------------
1 | require("element-ui/lib/button/style.css");
2 |
3 | var _Button = _interopRequireDefault(require("element-ui/lib/button")).default;
4 |
5 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6 |
7 | ReactDOM.render(React.createElement("div", {
8 | component: _Button
9 | }));
10 |
--------------------------------------------------------------------------------
/test/fixtures/specifier-alias/expected.js:
--------------------------------------------------------------------------------
1 | require("element-ui/lib/button/style.css");
2 |
3 | var _Button = _interopRequireDefault(require("element-ui/lib/button")).default;
4 |
5 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6 |
7 | ReactDOM.render(React.createElement("div", null, React.createElement(_Button, null, "xxxx")));
8 |
--------------------------------------------------------------------------------
/test/fixtures/react-element/expected.js:
--------------------------------------------------------------------------------
1 | require("element-ui/lib/button/style.css");
2 |
3 | var _Button = _interopRequireDefault(require("element-ui/lib/button")).default;
4 |
5 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6 |
7 | ReactDOM.render(React.createElement("div", null, React.createElement(_Button, null, "xxxx")));
8 |
9 |
--------------------------------------------------------------------------------
/test/fixtures/conditions/expected.js:
--------------------------------------------------------------------------------
1 | require("element-ui/lib/select/style.css");
2 |
3 | var _Select = _interopRequireDefault(require("element-ui/lib/select")).default;
4 |
5 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
6 |
7 | if (a === _Select) {}
8 |
9 | if (_Select) {}
10 |
11 | _Select ? 'a' : 'b';
12 | a ? _Select : 2;
13 | _Select || 'a';
14 | a || _Select;
15 |
--------------------------------------------------------------------------------
/test/fixtures/assignment-expression/expected.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | require("element-ui/lib/message-box/style.css");
4 |
5 | var _messageBox = _interopRequireDefault(require("element-ui/lib/message-box"));
6 |
7 | var _vue = _interopRequireDefault(require("vue"));
8 |
9 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10 |
11 | _vue.default.$prototype.$message = _messageBox.default;
12 |
--------------------------------------------------------------------------------
/test/fixtures/import-css/expected.js:
--------------------------------------------------------------------------------
1 | require("element-ui/lib/button/style.css");
2 |
3 | var _Button = _interopRequireDefault(require("element-ui/lib/button")).default;
4 |
5 | require("element-ui/lib/message/style.css");
6 |
7 | var _message = _interopRequireDefault(require("element-ui/lib/message")).default;
8 |
9 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10 |
11 | _message('xxx');
12 |
13 | ReactDOM.render(React.createElement("div", null, React.createElement(_Button, null, "xxxx")));
14 |
--------------------------------------------------------------------------------
/test/fixtures/custom-css-filename/expected.js:
--------------------------------------------------------------------------------
1 | require("element-ui/lib/button/style.css");
2 |
3 | var _Button = _interopRequireDefault(require("element-ui/lib/button")).default;
4 |
5 | require("element-ui/lib/message/style.css");
6 |
7 | var _message = _interopRequireDefault(require("element-ui/lib/message")).default;
8 |
9 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10 |
11 | _message('xxx');
12 |
13 | ReactDOM.render(React.createElement("div", null, React.createElement(_Button, null, "xxxx")));
14 |
--------------------------------------------------------------------------------
/test/fixtures/import-theme-custom/expected.js:
--------------------------------------------------------------------------------
1 | var _Alert2 = _interopRequireDefault(require("element-ui4/lib/theme-custom/alert.css")).default;
2 |
3 | var _Alert = _interopRequireDefault(require("element-ui4/lib/alert")).default;
4 |
5 | var _Button2 = _interopRequireDefault(require("element-ui4/lib/theme-custom/button.css")).default;
6 |
7 | var _Button = _interopRequireDefault(require("element-ui4/lib/button")).default;
8 |
9 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10 |
11 | console.log(_Button);
12 | console.log(_Alert);
13 |
--------------------------------------------------------------------------------
/test/fixtures/independent-theme-package-mixin/expected.js:
--------------------------------------------------------------------------------
1 | var _Alert2 = _interopRequireDefault(require("element-ui7/lib/alert/style.css")).default;
2 |
3 | var _Alert = _interopRequireDefault(require("element-ui7/lib/alert")).default;
4 |
5 | var _Button2 = _interopRequireDefault(require("element-ui7/lib/button/style.css")).default;
6 |
7 | var _Button = _interopRequireDefault(require("element-ui7/lib/button")).default;
8 |
9 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10 |
11 | console.log(_Button);
12 | console.log(_Alert);
13 |
--------------------------------------------------------------------------------
/test/fixtures/import-theme-custom-path/expected.js:
--------------------------------------------------------------------------------
1 | var _Alert2 = _interopRequireDefault(require("element-ui5/lib/theme-custom-path/alert/alert.css")).default;
2 |
3 | var _Alert = _interopRequireDefault(require("element-ui5/lib/alert")).default;
4 |
5 | var _Button2 = _interopRequireDefault(require("element-ui5/lib/theme-custom-path/button/button.css")).default;
6 |
7 | var _Button = _interopRequireDefault(require("element-ui5/lib/button")).default;
8 |
9 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10 |
11 | console.log(_Button);
12 | console.log(_Alert);
13 |
--------------------------------------------------------------------------------
/test/fixtures/independent-theme-package/expected.js:
--------------------------------------------------------------------------------
1 | var _Alert2 = _interopRequireDefault(require("__theme__/theme/alert.css")).default;
2 |
3 | require("__theme__/theme/base.css");
4 |
5 | var _Alert = _interopRequireDefault(require("element-ui3/lib/alert")).default;
6 |
7 | var _Button2 = _interopRequireDefault(require("__theme__/theme/button.css")).default;
8 |
9 | require("__theme__/theme/base.css");
10 |
11 | var _Button = _interopRequireDefault(require("element-ui3/lib/button")).default;
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | console.log(_Button);
16 | console.log(_Alert);
--------------------------------------------------------------------------------
/test/fixtures/independent-theme-package-custom/expected.js:
--------------------------------------------------------------------------------
1 | var _Alert2 = _interopRequireDefault(require("__theme__/theme/alert/alert.css")).default;
2 |
3 | require("__theme__/theme/base.css");
4 |
5 | var _Alert = _interopRequireDefault(require("element-ui6/lib/alert")).default;
6 |
7 | var _Button2 = _interopRequireDefault(require("__theme__/theme/button/button.css")).default;
8 |
9 | require("__theme__/theme/base.css");
10 |
11 | var _Button = _interopRequireDefault(require("element-ui6/lib/button")).default;
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | console.log(_Button);
16 | console.log(_Alert);
17 |
--------------------------------------------------------------------------------
/test/fixtures/import-theme/expected.js:
--------------------------------------------------------------------------------
1 | var _Alert2 = _interopRequireDefault(require("element-ui/lib/theme-default/alert.css")).default;
2 |
3 | require("element-ui/lib/theme-default/base.css");
4 |
5 | var _Alert = _interopRequireDefault(require("element-ui/lib/alert")).default;
6 |
7 | var _Button2 = _interopRequireDefault(require("element-ui/lib/theme-default/button.css")).default;
8 |
9 | require("element-ui/lib/theme-default/base.css");
10 |
11 | var _Button = _interopRequireDefault(require("element-ui/lib/button")).default;
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | console.log(_Button);
16 | console.log(_Alert);
17 |
--------------------------------------------------------------------------------
/test/fixtures/import-theme-all-compo/expected.js:
--------------------------------------------------------------------------------
1 | var _Alert2 = _interopRequireDefault(require("element-ui2/lib/alert")).default;
2 |
3 | var _Alert = _interopRequireDefault(require("element-ui2/lib/alert")).default;
4 |
5 | var _Button2 = _interopRequireDefault(require("element-ui2/lib/button")).default;
6 |
7 | var _Button = _interopRequireDefault(require("element-ui2/lib/button")).default;
8 |
9 | var _Components2 = _interopRequireDefault(require("element-ui2/lib/theme-default/index.css")).default;
10 |
11 | var _Components = _interopRequireDefault(require("element-ui2/lib")).default;
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | console.log(_Components);
16 | console.log(_Button, _Alert);
17 |
--------------------------------------------------------------------------------
/test/fixtures/multiple-module/expected.js:
--------------------------------------------------------------------------------
1 | require("antd/lib/alert2/style.css");
2 |
3 | var _Alert2 = _interopRequireDefault(require("antd/lib/alert2")).default;
4 |
5 | require("test-module/lib/alert/style.css");
6 |
7 | var _Alert = _interopRequireDefault(require("test-module/lib/alert")).default;
8 |
9 | require("antd/lib/button/style.css");
10 |
11 | var _Button = _interopRequireDefault(require("antd/lib/button")).default;
12 |
13 | require("antd/lib/message/style.css");
14 |
15 | var _message = _interopRequireDefault(require("antd/lib/message")).default;
16 |
17 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18 |
19 | _message('xxx');
20 |
21 | ReactDOM.render(React.createElement("div", null, React.createElement(_Button, null, "xxxx"), React.createElement(_Alert, null, "xxxx"), React.createElement(_Alert2, null, "xxx")));
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "babel-plugin-component",
3 | "version": "1.1.1",
4 | "description": "Modular build plugin for babel.",
5 | "main": "lib/index.js",
6 | "scripts": {
7 | "build": "rm -rf lib && babel src --out-dir lib --ignore __tests__",
8 | "test": "mocha --require @babel/register",
9 | "debug": "mocha --require @babel/register --require @babel/polyfill --no-timeouts",
10 | "lint": "eslint --ext .js src",
11 | "coveralls": "cat ./coverage/lcov.info | coveralls",
12 | "prepublish": "npm run build"
13 | },
14 | "pre-commit": [
15 | "lint"
16 | ],
17 | "keywords": [
18 | "babel-plugin"
19 | ],
20 | "author": [
21 | "chencheng ",
22 | "qingwei-li "
23 | ],
24 | "license": "MIT",
25 | "devDependencies": {
26 | "@babel/cli": "7.0.0-beta.35",
27 | "@babel/core": "7.0.0-beta.35",
28 | "@babel/node": "7.0.0-beta.35",
29 | "@babel/preset-env": "7.0.0-beta.35",
30 | "@babel/preset-react": "7.0.0-beta.35",
31 | "@babel/preset-stage-0": "7.0.0-beta.35",
32 | "@babel/register": "7.0.0-beta.35",
33 | "coveralls": "^2.11.6",
34 | "eslint": "^2.7.0",
35 | "eslint-config-airbnb": "^6.2.0",
36 | "expect": "^1.13.4",
37 | "mocha": "4.0.1",
38 | "pre-commit": "~1.1.2"
39 | },
40 | "repository": "ElementUI/babel-plugin-component",
41 | "homepage": "https://github.com/ElementUI/babel-plugin-component#readme",
42 | "bugs": {
43 | "url": "https://github.com/ElementUI/babel-plugin-component/issues"
44 | },
45 | "babel": {
46 | "presets": [
47 | "@babel/preset-env",
48 | "@babel/preset-react"
49 | ]
50 | },
51 | "files": [
52 | "lib",
53 | "package.json",
54 | "README.md"
55 | ],
56 | "dependencies": {
57 | "@babel/helper-module-imports": "7.0.0-beta.35"
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # babel-plugin-component
2 |
3 | [](https://npmjs.org/package/babel-plugin-component)
4 | [](https://travis-ci.org/ElementUI/babel-plugin-component)
5 | [](https://coveralls.io/github/QingWei-Li/babel-plugin-component?branch=master)
6 |
7 | ## Install
8 |
9 | ```shell
10 | npm i babel-plugin-component -D
11 |
12 | # For babel6
13 | npm i babel-plugin-component@0 -D
14 | ```
15 |
16 | ## Example
17 |
18 | Converts
19 |
20 | ```javascript
21 | import { Button } from 'components'
22 | ```
23 |
24 | to
25 |
26 | ```javascript
27 | var button = require('components/lib/button')
28 | require('components/lib/button/style.css')
29 | ```
30 |
31 | ## styleLibraryName Example
32 |
33 | Converts
34 |
35 | ```javascript
36 | import Components from 'components'
37 | import { Button } from 'components'
38 | ```
39 |
40 | to
41 |
42 | ```javascript
43 | require('components/lib/styleLibraryName/index.css')
44 | var button = require('components/lib/styleLibraryName/button.css')
45 | ```
46 |
47 | ## Usage
48 |
49 | Via `.babelrc` or babel-loader.
50 |
51 | ```javascript
52 | {
53 | "plugins": [["component", options]]
54 | }
55 | ```
56 |
57 | ## Multiple Module
58 | ```javascript
59 | {
60 | "plugins": [xxx,
61 | ["component", {
62 | libraryName: "antd",
63 | style: true,
64 | }, "antd"],
65 | ["component", {
66 | libraryName: "test-module",
67 | style: true,
68 | }, "test-module"]
69 | ]
70 | }
71 | ```
72 |
73 | ### Component directory structure
74 | ```
75 | - lib // 'libDir'
76 | - index.js // or custom 'root' relative path
77 | - style.css // or custom 'style' relative path
78 | - componentA
79 | - index.js
80 | - style.css
81 | - componentB
82 | - index.js
83 | - style.css
84 | ```
85 |
86 | ### Theme library directory structure
87 | ```
88 | - lib
89 | - theme-default // 'styleLibraryName'
90 | - base.css // required
91 | - index.css // required
92 | - componentA.css
93 | - componentB.css
94 | - theme-material
95 | - ...
96 | - componentA
97 | - index.js
98 | - componentB
99 | - index.js
100 | ```
101 | or
102 | ```
103 | - lib
104 | - theme-custom // 'styleLibrary.name'
105 | - base.css // if styleLibrary.base true
106 | - index.css // required
107 | - componentA.css // default
108 | - componentB.css
109 | - theme-material
110 | - componentA
111 | -index.css // styleLibrary.path [module]/index.css
112 | - componentB
113 | -index.css
114 | - componentA
115 | - index.js
116 | - componentB
117 | - index.js
118 | ```
119 |
120 | ### options
121 |
122 | - `["component"]`: import js modularly
123 | - `["component", { "libraryName": "component" }]`: module name
124 | - `["component", { "styleLibraryName": "theme_package" }]`: style module name
125 | - `["component", { "styleLibraryName": "~independent_theme_package" }]`: Import a independent theme package
126 | - `["component", { "styleLibrary": {} }]`: Import a independent theme package with more config
127 | ```
128 | styleLibrary: {
129 | "name": "xxx", // same with styleLibraryName
130 | "base": true, // if theme package has a base.css
131 | "path": "[module]/index.css", // the style path. e.g. module Alert => alert/index.css
132 | "mixin": true // if theme-package not found css file, then use [libraryName]'s css file
133 | }
134 | ```
135 | - `["component", { "style": true }]`: import js and css from 'style.css'
136 | - `["component", { "style": cssFilePath }]`: import style css from filePath
137 | - `["component", { "libDir": "lib" }]`: lib directory
138 | - `["component", { "root": "index" }]`: main file dir
139 | - `["component", { "camel2Dash": false }]`: whether parse name to dash mode or not, default `true`
140 |
--------------------------------------------------------------------------------
/test/index-test.js:
--------------------------------------------------------------------------------
1 | import { transformFileSync } from '@babel/core';
2 | import { join } from 'path';
3 | import { readdirSync, readFileSync } from 'fs';
4 | import plugin from '../src/index';
5 | import expect from 'expect';
6 | import { resolve } from 'path';
7 |
8 | describe('index', () => {
9 | const fixturesDir = join(__dirname, 'fixtures');
10 | let fixtures = readdirSync(fixturesDir);
11 | const onlyFixtures = fixtures.filter(fixture => fixture.indexOf('-only') > -1);
12 |
13 | if (onlyFixtures.length) {
14 | fixtures = onlyFixtures;
15 | }
16 |
17 | fixtures.map(caseName => {
18 | const fixtureDir = join(fixturesDir, caseName);
19 | const actualFile = join(fixtureDir, 'actual.js');
20 | const expectedFile = join(fixtureDir, 'expected.js');
21 | let expected = readFileSync(expectedFile, 'utf-8');
22 |
23 | it(`should work with ${caseName.split('-').join(' ')}`, () => {
24 |
25 | let cssPlugin;
26 | if (caseName === 'import-css') {
27 | cssPlugin = [plugin, {
28 | style: true,
29 | }];
30 | }
31 |
32 | if (caseName === 'import-module') {
33 | cssPlugin = [plugin, {
34 | style: true,
35 | root: 'abc',
36 | }];
37 | }
38 |
39 | if (caseName === 'import-all-css') {
40 | cssPlugin = [plugin, {
41 | style: true,
42 | }];
43 | }
44 |
45 | if (caseName === 'import-theme') {
46 | cssPlugin = [plugin, {
47 | libraryName: 'element-ui',
48 | styleLibraryName: 'theme-default',
49 | }];
50 | }
51 |
52 | if (caseName === 'import-theme-custom') {
53 | cssPlugin = [plugin, {
54 | libraryName: 'element-ui4',
55 | styleLibrary: {
56 | base: false,
57 | name: 'theme-custom',
58 | },
59 | }];
60 | }
61 |
62 | if (caseName === 'import-theme-custom-path') {
63 | cssPlugin = [plugin, {
64 | libraryName: 'element-ui5',
65 | styleLibrary: {
66 | base: false,
67 | name: 'theme-custom-path',
68 | path: '[module]/[module].css',
69 | },
70 | }];
71 | }
72 |
73 | if (caseName === 'import-theme-all-compo') {
74 | cssPlugin = [plugin, {
75 | libraryName: 'element-ui2',
76 | styleLibraryName: 'theme-default',
77 | }];
78 | }
79 |
80 | if (caseName === 'independent-theme-package') {
81 | expected = expected.replace(/__theme__/g, process.cwd());
82 | cssPlugin = [plugin, {
83 | libraryName: 'element-ui3',
84 | styleLibraryName: '~theme',
85 | }];
86 | }
87 |
88 | if (caseName === 'independent-theme-package-custom') {
89 | expected = expected.replace(/__theme__/g, process.cwd());
90 | cssPlugin = [plugin, {
91 | libraryName: 'element-ui6',
92 | styleLibrary: {
93 | base: true,
94 | name: '~theme',
95 | path: '[module]/[module].css',
96 | },
97 | }];
98 | }
99 |
100 | if (caseName === 'independent-theme-package-mixin') {
101 | cssPlugin = [plugin, {
102 | libraryName: 'element-ui7',
103 | styleLibrary: {
104 | mixin: true,
105 | name: '~theme',
106 | path: '[module]/[module].css',
107 | },
108 | style: true,
109 | }];
110 | }
111 |
112 | if (caseName === 'custom-css-filename') {
113 | cssPlugin = [plugin, { style: 'style.css' }];
114 | }
115 |
116 | if (caseName === 'multiple-module') {
117 | cssPlugin = [
118 | [plugin, {
119 | libraryName: 'antd',
120 | style: true,
121 | }, 'antd'],
122 | [plugin, {
123 | libraryName: 'test-module',
124 | style: true,
125 | }, 'test-module'],
126 | ];
127 | }
128 |
129 | if (caseName === 'camel-to-dash-option') {
130 | cssPlugin = [plugin, {
131 | libraryName: 'antd',
132 | camel2Dash: false,
133 | }];
134 | }
135 |
136 | const actual = transformFileSync(actualFile, {
137 | presets: ['@babel/react'],
138 | plugins: cssPlugin && Array.isArray(cssPlugin[1]) ? cssPlugin : [cssPlugin || plugin],
139 | }).code;
140 |
141 |
142 | if (onlyFixtures.length) {
143 | console.warn();
144 | console.warn(actual);
145 | }
146 |
147 | expect(actual.trim()).toEqual(expected.trim());
148 | });
149 | });
150 | });
151 |
--------------------------------------------------------------------------------
/src/core.js:
--------------------------------------------------------------------------------
1 | const { addSideEffect, addDefault } = require('@babel/helper-module-imports');
2 | const resolve = require('path').resolve;
3 | const isExist = require('fs').existsSync;
4 | const cache = {};
5 | const cachePath = {};
6 | const importAll = {};
7 |
8 | module.exports = function core(defaultLibraryName) {
9 | return ({ types }) => {
10 | let specified;
11 | let libraryObjs;
12 | let selectedMethods;
13 | let moduleArr;
14 |
15 | function parseName(_str, camel2Dash) {
16 | if (!camel2Dash) {
17 | return _str;
18 | }
19 | const str = _str[0].toLowerCase() + _str.substr(1);
20 | return str.replace(/([A-Z])/g, ($1) => `-${$1.toLowerCase()}`);
21 | }
22 |
23 | function importMethod(methodName, file, opts) {
24 | if (!selectedMethods[methodName]) {
25 | let options;
26 | let path;
27 |
28 | if (Array.isArray(opts)) {
29 | options = opts.find(option =>
30 | moduleArr[methodName] === option.libraryName ||
31 | libraryObjs[methodName] === option.libraryName
32 | ); // eslint-disable-line
33 | }
34 | options = options || opts;
35 |
36 | const {
37 | libDir = 'lib',
38 | libraryName = defaultLibraryName,
39 | style = true,
40 | styleLibrary,
41 | root = '',
42 | camel2Dash = true,
43 | } = options;
44 | let styleLibraryPath = options.styleLibraryPath;
45 | let _root = root;
46 | let isBaseStyle = true;
47 | let modulePathTpl;
48 | let styleRoot;
49 | let mixin = false;
50 | const ext = options.ext || '.css';
51 |
52 | if (root) {
53 | _root = `/${root}`;
54 | }
55 |
56 | if (libraryObjs[methodName]) {
57 | path = `${libraryName}/${libDir}${_root}`;
58 | if (!_root) {
59 | importAll[path] = true;
60 | }
61 | } else {
62 | path = `${libraryName}/${libDir}/${parseName(methodName, camel2Dash)}`;
63 | }
64 | const _path = path;
65 |
66 | selectedMethods[methodName] = addDefault(file.path, path, { nameHint: methodName });
67 | if (styleLibrary && typeof styleLibrary === 'object') {
68 | styleLibraryPath = styleLibrary.name;
69 | isBaseStyle = styleLibrary.base;
70 | modulePathTpl = styleLibrary.path;
71 | mixin = styleLibrary.mixin;
72 | styleRoot = styleLibrary.root;
73 | }
74 | if (styleLibraryPath) {
75 | if (!cachePath[libraryName]) {
76 | const themeName = styleLibraryPath.replace(/^~/, '');
77 | cachePath[libraryName] = styleLibraryPath.indexOf('~') === 0
78 | ? resolve(process.cwd(), themeName)
79 | : styleLibraryPath;
80 | }
81 |
82 | if (libraryObjs[methodName]) {
83 | /* istanbul ingore next */
84 | if (cache[libraryName] === 2) {
85 | throw Error('[babel-plugin-component] If you are using both' +
86 | 'on-demand and importing all, make sure to invoke the' +
87 | ' importing all first.');
88 | }
89 | if (styleRoot) {
90 | path = `${cachePath[libraryName]}${styleRoot}${ext}`;
91 | } else {
92 | path = `${cachePath[libraryName]}${_root || '/index'}${ext}`;
93 | }
94 | cache[libraryName] = 1;
95 | } else {
96 | if (cache[libraryName] !== 1) {
97 | /* if set styleLibrary.path(format: [module]/module.css) */
98 | const parsedMethodName = parseName(methodName, camel2Dash);
99 | if (modulePathTpl) {
100 | const modulePath = modulePathTpl.replace(/\[module]/ig, parsedMethodName);
101 | path = `${cachePath[libraryName]}/${modulePath}`;
102 | } else {
103 | path = `${cachePath[libraryName]}/${parsedMethodName}${ext}`;
104 | }
105 | if (mixin && !isExist(path)) {
106 | path = style === true ? `${_path}/style${ext}` : `${_path}/${style}`;
107 | }
108 | if (isBaseStyle) {
109 | addSideEffect(file.path, `${cachePath[libraryName]}/base${ext}`);
110 | }
111 | cache[libraryName] = 2;
112 | }
113 | }
114 |
115 | addDefault(file.path, path, { nameHint: methodName });
116 | } else {
117 | if (style === true) {
118 | addSideEffect(file.path, `${path}/style${ext}`);
119 | } else if (style) {
120 | addSideEffect(file.path, `${path}/${style}`);
121 | }
122 | }
123 | }
124 | return selectedMethods[methodName];
125 | }
126 |
127 | function buildExpressionHandler(node, props, path, state) {
128 | const file = (path && path.hub && path.hub.file) || (state && state.file);
129 | props.forEach(prop => {
130 | if (!types.isIdentifier(node[prop])) return;
131 | if (specified[node[prop].name]) {
132 | node[prop] = importMethod(node[prop].name, file, state.opts); // eslint-disable-line
133 | }
134 | });
135 | }
136 |
137 | function buildDeclaratorHandler(node, prop, path, state) {
138 | const file = (path && path.hub && path.hub.file) || (state && state.file);
139 | if (!types.isIdentifier(node[prop])) return;
140 | if (specified[node[prop].name]) {
141 | node[prop] = importMethod(node[prop].name, file, state.opts); // eslint-disable-line
142 | }
143 | }
144 |
145 | return {
146 | visitor: {
147 | Program() {
148 | specified = Object.create(null);
149 | libraryObjs = Object.create(null);
150 | selectedMethods = Object.create(null);
151 | moduleArr = Object.create(null);
152 | },
153 |
154 | ImportDeclaration(path, { opts }) {
155 | const { node } = path;
156 | const { value } = node.source;
157 | let result = {};
158 |
159 | if (Array.isArray(opts)) {
160 | result = opts.find(option => option.libraryName === value) || {};
161 | }
162 | const libraryName = result.libraryName || opts.libraryName || defaultLibraryName;
163 |
164 | if (value === libraryName) {
165 | node.specifiers.forEach(spec => {
166 | if (types.isImportSpecifier(spec)) {
167 | specified[spec.local.name] = spec.imported.name;
168 | moduleArr[spec.imported.name] = value;
169 | } else {
170 | libraryObjs[spec.local.name] = value;
171 | }
172 | });
173 |
174 | if (!importAll[value]) {
175 | path.remove();
176 | }
177 | }
178 | },
179 |
180 | CallExpression(path, state) {
181 | const { node } = path;
182 | const file = (path && path.hub && path.hub.file) || (state && state.file);
183 | const { name } = node.callee;
184 |
185 | if (types.isIdentifier(node.callee)) {
186 | if (specified[name]) {
187 | node.callee = importMethod(specified[name], file, state.opts);
188 | }
189 | } else {
190 | node.arguments = node.arguments.map(arg => {
191 | const { name: argName } = arg;
192 | if (specified[argName]) {
193 | return importMethod(specified[argName], file, state.opts);
194 | } else if (libraryObjs[argName]) {
195 | return importMethod(argName, file, state.opts);
196 | }
197 | return arg;
198 | });
199 | }
200 | },
201 |
202 | MemberExpression(path, state) {
203 | const { node } = path;
204 | const file = (path && path.hub && path.hub.file) || (state && state.file);
205 |
206 | if (libraryObjs[node.object.name] || specified[node.object.name]) {
207 | node.object = importMethod(node.object.name, file, state.opts);
208 | }
209 | },
210 |
211 | AssignmentExpression(path, { opts }) {
212 | if (!path.hub) {
213 | return;
214 | }
215 | const { node } = path;
216 | const { file } = path.hub;
217 |
218 | if (node.operator !== '=') return;
219 | if (libraryObjs[node.right.name] || specified[node.right.name]) {
220 | node.right = importMethod(node.right.name, file, opts);
221 | }
222 | },
223 |
224 | ArrayExpression(path, { opts }) {
225 | if (!path.hub) {
226 | return;
227 | }
228 | const { elements } = path.node;
229 | const { file } = path.hub;
230 |
231 | elements.forEach((item, key) => {
232 | if (item && (libraryObjs[item.name] || specified[item.name])) {
233 | elements[key] = importMethod(item.name, file, opts);
234 | }
235 | });
236 | },
237 |
238 | Property(path, state) {
239 | const { node } = path;
240 | buildDeclaratorHandler(node, 'value', path, state);
241 | },
242 |
243 | VariableDeclarator(path, state) {
244 | const { node } = path;
245 | buildDeclaratorHandler(node, 'init', path, state);
246 | },
247 |
248 | LogicalExpression(path, state) {
249 | const { node } = path;
250 | buildExpressionHandler(node, ['left', 'right'], path, state);
251 | },
252 |
253 | ConditionalExpression(path, state) {
254 | const { node } = path;
255 | buildExpressionHandler(node, ['test', 'consequent', 'alternate'], path, state);
256 | },
257 |
258 | IfStatement(path, state) {
259 | const { node } = path;
260 | buildExpressionHandler(node, ['test'], path, state);
261 | buildExpressionHandler(node.test, ['left', 'right'], path, state);
262 | },
263 | },
264 | };
265 | };
266 | };
267 |
--------------------------------------------------------------------------------