css.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.assetFileNamesToFileName = exports.uniCssPlugin = void 0;
  7. const fs_1 = __importDefault(require("fs"));
  8. const path_1 = __importDefault(require("path"));
  9. const vite_1 = require("vite");
  10. const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared");
  11. const shared_1 = require("@vue/shared");
  12. function isCombineBuiltInCss(config) {
  13. return config.command === 'build' && config.build.cssCodeSplit;
  14. }
  15. function uniCssPlugin() {
  16. let resolvedConfig;
  17. let file = '';
  18. let fileName = '';
  19. return {
  20. name: 'uni:h5-css',
  21. apply: 'build',
  22. enforce: 'pre',
  23. configResolved(config) {
  24. resolvedConfig = config;
  25. file = path_1.default.join(process.env.UNI_INPUT_DIR, 'uni.css');
  26. },
  27. async generateBundle() {
  28. if (!isCombineBuiltInCss(resolvedConfig) || !uni_cli_shared_1.buildInCssSet.size) {
  29. return;
  30. }
  31. // 生成框架css(需要排序,避免生成不一样的内容)
  32. const content = await (0, uni_cli_shared_1.minifyCSS)(generateBuiltInCssCode([...uni_cli_shared_1.buildInCssSet].sort()), resolvedConfig);
  33. // @ts-ignore 'Buffer' only refers to a type, but is being used as a value here
  34. const contentHash = (0, uni_cli_shared_1.getAssetHash)(Buffer.from(content, 'utf-8'));
  35. const assetFileNames = path_1.default.posix.join(resolvedConfig.build.assetsDir, '[name].[hash][extname]');
  36. fileName = assetFileNamesToFileName(assetFileNames, file, contentHash, content);
  37. const name = (0, vite_1.normalizePath)(path_1.default.relative(resolvedConfig.root, file));
  38. this.emitFile({
  39. name,
  40. fileName,
  41. type: 'asset',
  42. source: content,
  43. });
  44. },
  45. transformIndexHtml: {
  46. enforce: 'post',
  47. transform() {
  48. if (!fileName) {
  49. return;
  50. }
  51. // 追加框架css
  52. return [
  53. {
  54. tag: 'link',
  55. attrs: {
  56. rel: 'stylesheet',
  57. href: toPublicPath(fileName, resolvedConfig),
  58. },
  59. injectTo: 'head-prepend',
  60. },
  61. ];
  62. },
  63. },
  64. };
  65. }
  66. exports.uniCssPlugin = uniCssPlugin;
  67. function toPublicPath(filename, config) {
  68. return (0, uni_cli_shared_1.isExternalUrl)(filename) ? filename : config.base + filename;
  69. }
  70. function generateBuiltInCssCode(cssImports) {
  71. return cssImports
  72. .map((cssImport) => fs_1.default.readFileSync((0, uni_cli_shared_1.resolveBuiltIn)(cssImport), 'utf8'))
  73. .join('\n');
  74. }
  75. /**
  76. * converts the source filepath of the asset to the output filename based on the assetFileNames option. \
  77. * this function imitates the behavior of rollup.js. \
  78. * https://rollupjs.org/guide/en/#outputassetfilenames
  79. *
  80. * @example
  81. * ```ts
  82. * const content = Buffer.from('text');
  83. * const fileName = assetFileNamesToFileName(
  84. * 'assets/[name].[hash][extname]',
  85. * '/path/to/file.txt',
  86. * getAssetHash(content),
  87. * content
  88. * )
  89. * // fileName: 'assets/file.982d9e3e.txt'
  90. * ```
  91. *
  92. * @param assetFileNames filename pattern. e.g. `'assets/[name].[hash][extname]'`
  93. * @param file filepath of the asset
  94. * @param contentHash hash of the asset. used for `'[hash]'` placeholder
  95. * @param content content of the asset. passed to `assetFileNames` if `assetFileNames` is a function
  96. * @returns output filename
  97. */
  98. function assetFileNamesToFileName(assetFileNames, file, contentHash, content) {
  99. const basename = path_1.default.basename(file);
  100. // placeholders for `assetFileNames`
  101. // `hash` is slightly different from the rollup's one
  102. const extname = path_1.default.extname(basename);
  103. const ext = extname.slice(1);
  104. const name = basename.slice(0, -extname.length);
  105. const hash = contentHash;
  106. if ((0, shared_1.isFunction)(assetFileNames)) {
  107. assetFileNames = assetFileNames({
  108. name: file,
  109. source: content,
  110. type: 'asset',
  111. });
  112. if (!(0, shared_1.isString)(assetFileNames)) {
  113. throw new TypeError('assetFileNames must return a string');
  114. }
  115. }
  116. else if (!(0, shared_1.isString)(assetFileNames)) {
  117. throw new TypeError('assetFileNames must be a string or a function');
  118. }
  119. const fileName = assetFileNames.replace(/\[\w+\]/g, (placeholder) => {
  120. switch (placeholder) {
  121. case '[ext]':
  122. return ext;
  123. case '[extname]':
  124. return extname;
  125. case '[hash]':
  126. return hash;
  127. case '[name]':
  128. return name;
  129. }
  130. throw new Error(`invalid placeholder ${placeholder} in assetFileNames "${assetFileNames}"`);
  131. });
  132. return fileName;
  133. }
  134. exports.assetFileNamesToFileName = assetFileNamesToFileName;