【问题标题】:Published npm package does not apply styles发布的 npm 包不应用样式
【发布时间】:2020-07-02 04:10:02
【问题描述】:

我目前正在创建一个npm package。这基本上是一个使用 SCSS 添加样式的 React 组件。当我测试它时,类名在那里,但没有应用任何样式。

这是package 的存储库。我使用单独的 webpack 配置来构建组件所在的特定文件夹。

这是我正在使用的 webpack 配置:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const EsLintFormatter = require('eslint-formatter-pretty');
const path = require('path');

const pkg = require('../../package.json');
const { SRC_PATH, BUILD_PATH } = require('./constants');
const setStyleLoaders = require('./style-loaders');
const alias = require('./alias');

const packageName = pkg.name;

module.exports = ({ NODE_ENV }) => ({
  mode: 'production',
  entry: `${SRC_PATH}/components/Carousel/Carousel.js`,
  output: {
    path: BUILD_PATH,
    filename: 'index.js',
    library: packageName,
    libraryTarget: 'commonjs2',
    umdNamedDefine: true,
    publicPath: '/build/',
  },
  node: {
    net: 'empty',
    tls: 'empty',
    dns: 'empty',
  },
  resolve: {
    alias: {
      ...alias,
      react: path.resolve(__dirname, './node_modules/react'),
      'react-dom': path.resolve(__dirname, './node_modules/react-dom'),
    },
  },
  externals: {
    react: 'react',
    reactDom: 'react-dom',
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        use: [
          { loader: 'babel-loader' },
          {
            loader: 'eslint-loader',
            options: {
              formatter: EsLintFormatter,
            },
          },
        ],
      },
      {
        test: /\.(sa|sc|c)ss$/,
        use: setStyleLoaders(NODE_ENV),
      },
      {
        test: /\.(png|pje?g|gif|svg)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              outputPath: 'images',
            },
          },
        ],
      },
      {
        test: /\.(woff|woff2|tff|otf|eot)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              outputPath: 'fonts',
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({ filename: 'index.css' }),
  ],
});

...这是我的 package.json

{
  "name": "react-clear-carousel",
  "version": "0.1.0-beta.1",
  "description": "A test",
  "main": "build/index.js",
  "scripts": {
    "start": "cross-env NODE_ENV=development webpack-dev-server --env.NODE_ENV=development --config config/webpack/webpack.config.js",
    "build": "cross-env NODE_ENV=production webpack --env.NODE_ENV=production --config config/webpack/webpack.config.publish.js",
    "stylelint": "stylelint 'src/**/*.scss' --config stylelint.config.js; exit 0",
    "eslint": "eslint 'src/**/*.js'; exit 0",
    "es:fix": "eslint 'src/**/*.js' --fix",
    "style:fix": "stylelint 'src/**/*.scss' --fix",
    "lint": "npm run eslint && npm run stylelint",
    "publish:beta": "npm publish --tag=beta",
    "test": "jest"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/RobCC/web-playground.git"
  },
  "author": "robcc",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/RobCC/web-playground/issues"
  },
  "files": [
    "dist"
  ],
  "jest": {
    "setupFilesAfterEnv": [
      "<rootDir>/config/jest/setup.js"
    ],
    "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/config/jest/fileMock.js",
      "\\.(css|less|scss)$": "identity-obj-proxy",
      "^~/(.*)": "<rootDir>/$1",
      "^#/(.*)": "<rootDir>/src/$1"
    }
  },
  "homepage": "https://github.com/RobCC/web-playground#readme",
  "peerDependencies": {
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "prop-types": "^15.7.2"
  },
  "devDependencies": {
    "@babel/cli": "^7.8.4",
    "@babel/core": "^7.9.0",
    "@babel/plugin-proposal-class-properties": "^7.8.3",
    "@babel/plugin-proposal-export-default-from": "^7.8.3",
    "@babel/plugin-proposal-export-namespace-from": "^7.8.3",
    "@babel/preset-env": "^7.9.0",
    "@babel/preset-react": "^7.9.1",
    "@types/jest": "^25.1.4",
    "@types/node": "^13.9.2",
    "@types/react": "^16.9.25",
    "@types/react-dom": "^16.9.5",
    "@welldone-software/why-did-you-render": "^4.0.5",
    "autoprefixer": "^9.7.4",
    "babel-eslint": "^10.1.0",
    "babel-loader": "^8.1.0",
    "chalk": "^3.0.0",
    "clean-webpack-plugin": "^3.0.0",
    "core-js": "^3.6.4",
    "cross-env": "^7.0.2",
    "css-loader": "^3.4.2",
    "cssnano": "^4.1.10",
    "enzyme": "^3.11.0",
    "enzyme-adapter-react-16": "^1.15.2",
    "eslint": "^6.8.0",
    "eslint-config-airbnb": "^18.1.0",
    "eslint-formatter-pretty": "^3.0.1",
    "eslint-import-resolver-alias": "^1.1.2",
    "eslint-loader": "^3.0.3",
    "eslint-plugin-import": "^2.20.1",
    "eslint-plugin-jsx-a11y": "^6.2.3",
    "eslint-plugin-react": "^7.19.0",
    "eslint-plugin-react-hooks": "^2.5.1",
    "file-loader": "^6.0.0",
    "html-webpack-plugin": "^3.2.0",
    "identity-obj-proxy": "^3.0.0",
    "jest": "^25.1.0",
    "log-symbols": "^3.0.0",
    "mini-css-extract-plugin": "^0.9.0",
    "postcss-loader": "^3.0.0",
    "pr*op-types": "^15.7.2",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "regenerator-runtime": "^0.13.5",
    "sass": "^1.26.3",
    "sass-loader": "^8.0.2",
    "style-loader": "^1.1.3",
    "stylelint": "^13.2.1",
    "stylelint-config-recommended": "^3.0.0",
    "stylelint-formatter-pretty": "^2.0.0",
    "stylelint-scss": "^3.16.0",
    "stylelint-webpack-plugin": "^1.2.3",
    "ts-loader": "^6.2.1",
    "typescript": "^3.8.3",
    "webpack": "^4.42.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.10.3"
  },
  "dependencies": {
    "weak-key": "^1.0.2"
  }
}

这是测试发布包时的结果:

编辑 1:

devtools 中的网络和控制台选项卡上没有错误。我也找不到加载的文件,即使它在包中。 js文件好像没有使用,但是应该使用。

编辑 2:

感谢您为我指明正确的方向!

我添加了 import 'react-clear-carousel/build/index.css'; 以包含我的包中的 CSS 文件。我现在可以看到该文件(在 devtools 上),但是由于 css-loader 正在对其进行模块化并添加额外的后缀和前缀(即使它已经拥有它们),因此没有应用样式,因此具有与我的组件不同的类名有。

eg. 我的组件渲染为&lt;div class="carousel_swimlane--kXSjh"&gt;,但DOM 中的样式命名为index_carousel_swimlane--kXSjh--2C

我想现在的问题是,我如何告诉 Webpack 按原样传递这个 CSS?如果有办法让我在无需其他人更改 Webpack 配置的情况下交付 CSS 文件。

【问题讨论】:

  • 疑难解答:你的样式表加载成功了吗?网络选项卡中没有 404?下一个最简单的测试是清除浏览器缓存。
  • “网络”选项卡中没有 404 错误。我也找不到加载的文件,即使它在包中。好像js文件没有使用,但是应该
  • 听起来资产要么编译为空,要么未加载。您需要验证内容是否存在。
  • CSS 文件在那里。如果我在 node_modules 中检查它的文件夹,CSS 和 JS 文件都在那里。并且由于类名被正确应用,这意味着 CSS 文件就在那里。代码库(它有我的包作为依赖项)只是没有应用这些样式

标签: javascript reactjs npm webpack


【解决方案1】:

查看您的 repo,我看到您正在导入 scss,但将其属性归因于 classNames。

className 应该是类的名称,您可以将导入的样式归因于 style,或者您可以使用 &lt;link rel="stylesheet" type="text/css" href="styles.min.css"&gt; 将编译后的 css 加载到 DOM 中

您没有在网络选项卡中看到样式表的原因是您忘记声明样式表。

【讨论】:

  • 但是考虑到我想与其他人共享这个组件及其样式,我如何告诉他们的代码库包含那个 CSS 文件并应用我的组件需要的样式? CSS 文件已经在 node_modules 上,只是没有被使用
  • 所有包都需要使用说明,我相信,所以我想说这些说明之一应该是它们需要包含在其 HTML 中的 HTML 链接元素。将其命名为独特的,这样它就不会与其他样式表竞争,例如,指示用户将链接放置在引导程序之后但自定义样式表之前,并使用非常特定的 css 选择器和独特的命名约定,以便用户可以根据需要覆盖样式。
  • 我尝试从 node_modules 导入 css 文件(import 'react-clear-carousel/build/index.css')。我可以在 devtools 的 Sources 选项卡中看到 CSS 文件,但仍然没有应用样式。
  • 你在 DOM 中有那个链接元素吗?必须明确告知浏览器它是一个样式表,并且用于在该文档中使用。
  • 最终问题出在我的 Webpack 配置上。我在使用 CRA 的项目上尝试了我的包,添加了导入以从 node_modules 中提取 CSS,然后就做到了。起初我有一个误解,认为 CSS 应该自动拉取,因为 JS 正在使用它。感谢您的澄清并为我指明正确的方向。我会将您的答案标记为已接受。
猜你喜欢
  • 1970-01-01
  • 2020-11-17
  • 1970-01-01
  • 1970-01-01
  • 2021-06-18
  • 2021-02-11
  • 2022-06-27
  • 1970-01-01
  • 2021-05-24
相关资源
最近更新 更多