1. Create a project
mkdir component-template && cd component-template
npm init
npm init
The project name, version, description and other information will pop up, just fill in according to your needs.
After executing the above shell command, an package.json
empty project containing it will be generated. We modify the file directory as follows:
component-template
├─ config
│ ├─ webpack.config.base.js
│ ├─ webpack.config.dev.js
│ └─ webpack.config.prod.js
├─ demo // 测试组件用
│ ├─ index.html
│ └─ index.js
├─ src // 源代码目录
│ ├─ index.js
│ └─ index.less
├─ babel.config.json
└─ package.json
2. Install dependencies
-
Install React related dependencies
npm i react react-dom --save-dev
-
Install webpack related dependencies
npm i webpack webpack-cli webpack-dev-server webpack-merge clean-webpack-plugin --save-dev
Among them, clean-webpack-plugin
it is to clear the previous content for each package.
-
Install babel related dependencies
npm i @babel/cli @babel/core @babel/preset-env @babel/preset-react --save-dev
-
Install babel-loader
npm i babel-loader --save-dev
-
Install style-related loaders (here use less to develop components)
npm i style-loader css-loader less less-loader --save-dev
3. Configure webpack
-
config webpack.config.base.js
as public config
const path = require('path');
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.css$/,
exclude: /node_modules/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true
}
}
]
},
{
test: /\.less$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true
}
},
'less-loader'
]
},
{
test: /\.(jpg|jpeg|png|gif|svg)$/,
type: 'asset',
parser: {
// 转base64条件
dataUrlCondition: {
maxSize: 8 * 1024
}
},
generator: {
filename: 'img/[name].[hash:6][ext]'
}
}
]
},
// 配置下别名和扩展名优先级, 为了引入时书写方便
resolve: {
alias: {
'@': path.resolve(__dirname, '../src/')
},
extensions: ['.js', '.jsx', '.json']
}
};
-
Configure webpack.config.dev.js
as a development configuration
const path = require('path');
const { merge } = require('webpack-merge');
const baseConfig = require('./webpack.config.base.js');
const devConfig = {
mode: 'development',
entry: path.join(__dirname, '../demo/index.js'),
output: {
path: path.join(__dirname, '../demo/'),
filename: 'bundle.js'
},
devServer: {
static: path.join(__dirname, '../demo/'),
compress: true,
host: '127.0.0.1',
port: 8899,
open: true
}
};
module.exports = merge(devConfig, baseConfig);
It should be noted that the development configuration is to preview the effect in real time, and the entry is demo/index.js
. The package generated bundle.js
is in memory, not actually generated in the demo folder.
-
Configure webpack.config.prod.js
as packaged configuration:
const path = require('path');
const { merge } = require('webpack-merge');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const baseConfig = require('./webpack.config.base.js'); // 引用公共的配置
const prodConfig = {
mode: 'production',
entry: path.join(__dirname, '../src/index.js'),
output: {
path: path.join(__dirname, '../lib/'),
filename: 'index.js',
libraryTarget: 'umd',
libraryExport: 'default'
},
plugins: [new CleanWebpackPlugin()],
optimization: {
minimize: true
},
externals: {
// 外部依赖
react: {
root: 'React',
commonjs2: 'react',
commonjs: 'react',
amd: 'react'
},
'react-dom': {
root: 'ReactDOM',
commonjs2: 'react-dom',
commonjs: 'react-dom',
amd: 'react-dom'
}
}
};
module.exports = merge(prodConfig, baseConfig);
4. Configure babel
Configure in babel.config.js
:
module.exports = {
presets: ['@babel/preset-env', '@babel/preset-react']
};
So far, all configurations have been completed. Next we develop the components.
5. Development components
We write a simple component. A box with a width and height of 200px, the text is centered horizontally and vertically.
// src/index.js:
import React from 'react';
import styles from './index.less';
const Test = (props) => {
const { text = '测试' } = props;
return (
<>
<div className={styles.box}>{text}</div>
</>
);
};
export default Test;
// src/index.less
.box {
display: flex;
justify-content: center;
align-items: center;
width: 200px;
height: 200px;
font-size: 16px;
color: #fff;
background-color: #ff0000;
}
6. Test effect
Add demo/index.html
the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script src="./bundle.js"></script>
</body>
</html>
In demo/index.js
add the following code:
import React from 'react';
import { render } from 'react-dom';
import Test from '../src';
const App = () => (
<div style={
{ width: '100vw', height: '100vh' }}>
<Test text='哈哈' />
</div>
);
render(<App />, document.getElementById('root'));
Modify package.json
the run script, as follows:
...
"scripts": {
"start": "webpack-dev-server --config config/webpack.config.dev.js",
"build": "webpack --config config/webpack.config.prod.js",
"pub": "npm run build && npm publish"
},
...
npm run start
Take a look at component effects. Confirm that there is no problem, then we will npm run build
pack it.
7. Release
根据自己需要,书写使用文档 README.md
, 添加一下.npmignore
,如下:
node_modules/
src/
demo/
config/
babel.config.json
.gitignore
npm login
登录自己的账号
在项目根目录,npm publish
即可发布自己的 npm 包。
到 npm 平台上打开自己的账户,就可以查看自己的 npm 包了。
本文由 mdnice 多平台发布