UNPKG

6.13 kBJavaScriptView Raw
1"use strict";
2
3exports.__esModule = true;
4exports.default = plugin;
5
6var _fs = require("fs");
7
8var _path = require("path");
9
10var _generator = _interopRequireDefault(require("@babel/generator"));
11
12var _traverse = require("@babel/traverse");
13
14var t = _interopRequireWildcard(require("@babel/types"));
15
16var _commonTags = require("common-tags");
17
18var _defaults = _interopRequireDefault(require("lodash/defaults"));
19
20var _cssProp = _interopRequireDefault(require("./features/css-prop"));
21
22var _styledComponent = _interopRequireDefault(require("./features/styled-component"));
23
24var _stylesheet = _interopRequireDefault(require("./features/stylesheet"));
25
26var _ImportInjector = _interopRequireDefault(require("./utils/ImportInjector"));
27
28var _Symbols = require("./utils/Symbols");
29
30var _getName = _interopRequireDefault(require("./utils/getName"));
31
32function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
33
34function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
35
36function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
37
38// @ts-ignore
39function plugin() {
40 return {
41 pre(file) {
42 file.set(_Symbols.IMPORTS, []);
43
44 if (!file.has(_Symbols.STYLES)) {
45 file.set(_Symbols.STYLES, {
46 id: 0,
47 changeset: [],
48 styles: new Map()
49 });
50 }
51
52 if (!file.has(_Symbols.COMPONENTS)) {
53 file.set(_Symbols.COMPONENTS, new Map());
54 }
55 },
56
57 post(file) {
58 const {
59 opts
60 } = this; // eslint-disable-next-line prefer-const
61
62 let {
63 styles,
64 changeset
65 } = file.get(_Symbols.STYLES);
66 const styleList = Array.from(styles.values());
67 changeset = changeset.concat(styleList);
68 file.metadata.astroturf = {
69 styles: styleList,
70 changeset
71 };
72
73 if (opts.writeFiles !== false) {
74 styles.forEach(({
75 absoluteFilePath,
76 value
77 }) => {
78 // @ts-ignore
79 (0, _fs.mkdirSync)((0, _path.dirname)(absoluteFilePath), {
80 recursive: true
81 });
82 (0, _fs.writeFileSync)(absoluteFilePath, (0, _commonTags.stripIndent)([value]));
83 });
84 }
85 },
86
87 visitor: _traverse.visitors.merge([{
88 Program: {
89 enter(path, state) {
90 state.styleImports = new _ImportInjector.default(path);
91 state.defaultedOptions = (0, _defaults.default)(state.opts, {
92 extension: '.module.css',
93 cssTagName: 'css',
94 styledTagName: 'styled',
95 stylesheetTagName: 'stylesheet',
96 allowGlobal: false,
97 enableCssProp: true,
98 jsxPragma: true,
99 enableDynamicInterpolations: 'cssProp',
100 experiments: {}
101 });
102 const pragma = state.defaultedOptions.jsxPragma; // We need to re-export Fragment because of
103 // https://github.com/babel/babel/pull/7996#issuecomment-519653431
104
105 state[_Symbols.JSX_IDENTS] = {
106 jsx: typeof pragma === 'string' ? t.identifier(pragma) : path.scope.generateUidIdentifier('j')
107 };
108 }
109
110 },
111 ImportDeclaration: {
112 exit(path, state) {
113 const {
114 cssTagName,
115 stylesheetTagName
116 } = state.defaultedOptions;
117 const specifiers = path.get('specifiers');
118 const tagImports = path.get('specifiers').filter(p => p.isImportSpecifier() && ['css', 'stylesheet'].includes((0, _getName.default)(p.node.imported)) && [cssTagName, stylesheetTagName].includes(p.node.local.name));
119 if (!tagImports.length) return; // if the tagImports are ALL of the imported values then we want
120 // to pass the entire import to be removed.
121
122 state.file.get(_Symbols.IMPORTS).push({
123 path,
124 specifiers: specifiers.length === tagImports.length ? null : tagImports
125 });
126 }
127
128 }
129 }, _cssProp.default, _styledComponent.default, _stylesheet.default, {
130 Program: {
131 exit(_, {
132 opts,
133 file,
134 styleImports
135 }) {
136 // eslint-disable-next-line prefer-const
137 let {
138 changeset
139 } = file.get(_Symbols.STYLES);
140 const importNodes = file.get(_Symbols.IMPORTS);
141 importNodes.forEach(({
142 path,
143 specifiers
144 }) => {
145 if (!path) return;
146 const {
147 start,
148 end
149 } = path.node;
150
151 if (specifiers) {
152 specifiers.forEach(s => s.remove());
153 } else {
154 path.remove();
155 }
156
157 if (opts.generateInterpolations) changeset.push({
158 type: 'import-optimization',
159 start: start,
160 end: end,
161 // if the path is just a removed specifier we need to regenerate
162 // the import statement otherwise we remove the entire declaration
163 code: specifiers ? (0, _generator.default)(path.node).code : ''
164 });
165 });
166 changeset.push(styleImports.inject());
167 }
168
169 }
170 }])
171 };
172}
\No newline at end of file