我正在为可共享的UI组件创建一个单独的存储库。我正在使用styled-component
。当我使用npm link
在本地发布软件包时。抛出错误。
错误已说明here。
Project
|
+-- node_modules
|
+-- styled-component v4.0.2
|
+-- ui-component
|
+-- styled-component v4.1.1
有几种方法可以修复它,就像在link中提到的那样。
npm dedupe
(不适用于开发环境,因为它不能与npm link
一起很好地工作)。虽然有两个想法,但我有两个想法。
首先,两种解决方案都迫使最终用户在您的终端做某事。我希望使其像其他npm
软件包一样在其中安装和使用,而无需告诉用户在配置级别做些什么。
第二,为什么我必须这样做。我已经在webpack
中设置了所有内容。我要求webpack
不要对特定的软件包使用它自己的依赖关系,而要使用最终用户软件包。
其他npm
包的工作方式取决于父依赖关系,但它们在开发过程中使用自己的依赖关系。像react
这是我可共享的UI组件库中的文件。
Package.json
{
"name": "ui-component",
"version": "1.0.0",
"description": "Shareable web UI component",
"main": "build/index.js",
"scripts": {
"dev": "start-storybook -p 6006",
"build": "webpack",
"build:storybook": "build-storybook",
"test": "jest --env=jsdom",
"lint": "eslint"
},
"jest": {
"coverageThreshold": {
"global": {
"branches": 80,
"functions": 80,
"lines": 80,
"statements": 80
}
},
"collectCoverageFrom": [
"src/**/*.{js,jsx}",
"!storybook-static/**/*.{js,jsx}",
"!congif/**/*.{js,jsx}"
],
"setupFiles": [
"<rootDir>/src/enzymeSetup.js"
],
"testMatch": [
"<rootDir>/src/**/?(*.)(spec|test).{js,jsx,mjs}"
],
"testEnvironment": "node",
"testURL": "http://localhost",
"transform": {
"^.+\\.(js|jsx|mjs)$": "<rootDir>/node_modules/babel-jest"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$"
],
"testPathIgnorePatterns": [
"<rootDir>/__tests__/setup/"
],
"moduleNameMapper": {
"^@theme": "<rootDir>/src/theme.js",
"^@validation": "<rootDir>/src/validation/index.js",
"^@helper": "<rootDir>/src/helper.js"
},
"moduleFileExtensions": [
"web.js",
"js",
"json",
"web.jsx",
"jsx",
"node",
"mjs"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.js": [
"npm run lint --fix",
"cross-env CI=true npm test -- --coverage --bail --findRelatedTests"
]
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@material-ui/core": "^3.5.1",
"@material-ui/icons": "^3.0.1",
"react": "^16.6.3",
"react-router-dom": "^4.3.1",
"styled-components": "^4.1.1"
},
"devDependencies": {
"@babel/core": "^7.1.6",
"babel-core": "7.0.0-bridge.0",
"@babel/preset-env": "^7.1.6",
"@babel/preset-react": "^7.0.0",
"@storybook/addon-actions": "^4.0.7",
"@storybook/addon-centered": "^4.0.7",
"@storybook/addon-info": "^4.0.7",
"@storybook/addon-links": "^4.0.7",
"@storybook/addon-options": "^4.0.7",
"@storybook/addons": "^4.0.7",
"@storybook/components": "^4.0.7",
"@storybook/react": "^4.0.7",
"babel-eslint": "^9.0.0",
"babel-jest": "^23.6.0",
"babel-loader": "^8.0.4",
"css-loader": "^1.0.1",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.6.0",
"eslint": "^5.9.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-jsx-a11y": "^6.1.2",
"eslint-plugin-react": "^7.11.1",
"file-loader": "^2.0.0",
"husky": "^1.1.2",
"jest": "^23.6.0",
"lint-staged": "^8.0.4",
"react-dom": "^16.6.3",
"react-router-dom": "^4.3.1",
"storybook-styled-components": "^1.1.2",
"style-loader": "^0.23.1",
"webpack": "^4.26.0",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.10"
},
"peerDependencies": {
"react": "^16.5.2",
"styled-components": "^4.1.1"
}
}
Webpack
const path = require ('path');
module.exports = {
entry: {
main: './src/index.js',
},
output: {
path: path.resolve(__dirname, './build'),
filename: 'index.js',
libraryTarget: 'commonjs2',
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
}],
}
],
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'all',
}
}
}
},
plugins: [],
resolve: {
alias: {
'@theme': path.resolve(__dirname, './src/theme.js'),
'@validation': path.resolve(__dirname, './src/validation/index.js'),
'@helper': path.resolve(__dirname, './src/helper.js'),
}
},
externals: {
'react': 'commonjs react', // this line is just to use the React dependency of our parent-testing-project instead of using our own React.
'styled-components': 'commonjs styled-components' // this line is just to use the React dependency of our parent-testing-project instead of using our own styled-component.
}
}
我的父应用程序正在使用styled-components ^4.0.2
,而我的可共享ui库则使用样式组件“ styled-components”:“ ^ 4.1.1”。
我在peerDependencies
和webpack
中都有一个条目。奋斗超过一天的人,将不胜感激。
答案 0 :(得分:1)
请参阅正式的样式化组件文档中的this FAQ entry。在大多数情况下,向webpack配置添加别名足以解决该问题:
resolve: {
+ alias: {
+ "styled-components": path.resolve("./node_modules", "styled-components"),
+ }
}
答案 1 :(得分:0)
我花费了数小时尝试各种方法来克服这个问题,包括styled-components
文档中的所有内容,但都没有运气。直到我找到this suggestion on GitHub,一切都没有。
在Webpack配置中添加以下内容,可以告诉它对所有入口点使用单个运行时,而不是为每个入口点创建新的运行时。
optimization: {
runtimeChunk: {
name: "vendor"
},
....
答案 2 :(得分:0)
我也遇到了这个问题,以某种方式,我认为您有时无法加载styled-components
的两个版本,即使它们是相同版本,例如。 4.4.1
。
所以最后,我必须使用peerDependencies
,幸运的是我可以控制所有存储库,因此我将styled-components
移到了peerDependencies
的核心库中。然后仅依靠实施仓库中的一个副本。
我仍然可以闻到这里的气味,但是到目前为止,我只能让ThemeProvider
在不同的存储库中以这种方式工作。