我们在上一篇文章已经介绍过使用rollpkg
进行打包发布,这篇我们介绍一下如何使用webpack
进行打包,毕竟在工作中,使用webpack
的频率更高;
首先初始化项目
npx create-react-app [project-name] --template typescript
在src/
文件夹新建 /packages
文件夹,也可以为其他名字
,这个就是用来要发布的 npm包
内容;
安装 webpack 及 ts 相关依赖
npm install webpack ts-loader
- 添加 webpack 打包相关内容
-
在根目录新建 config 文件夹
webpack.config.js
const { resolve } = require('path')
module.exports = {
mode: 'production',
entry: resolve(__dirname, '../src/packages/index.ts'),
output: {
filename: 'index.js',
clean: true,
library: {
name: 'NpmName',
type: 'umd',
},
},
module: {
rules: [
{
test: /\.tsx?$/,
use: {
loader: 'ts-loader',
options: {
configFile: resolve(__dirname, './tsconfig.json'),
},
},
},
{
test: /\.(less|css)$/,
use: [
'style-loader',
'css-loader',
{
loader: 'less-loader',
options: {
lessOptions: {
javascriptEnabled: true,
},
},
},
],
},
{
test: /\.svg$/,
use: [
{
loader: 'svg-sprite-loader',
options: {
symbolId: 'icon-[name]',
},
},
],
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
alias: {
'@': resolve(__dirname, '../src'),
},
},
}
package.json
{
"name": "npm_name",
"version": "0.1.0",
"description": "",
"main": "lib/index.js",
"keywords": [],
"author": "xiaohuihui",
"license": "ISC",
"publishConfig": {
"registry": "xxx" // npm 发布地址
}
}
package.js
const path = require('path')
const fse = require('fs-extra')
const webpack = require('webpack')
const chalk = require('chalk')
const Spinner = require('cli-spinner').Spinner
const shell = require('shelljs')
function pathResolve(dir) {
return path.resolve(__dirname, dir)
}
var spinner = new Spinner(chalk.green('%s Packing...'))
spinner.setSpinnerString('⣾⣽⣻⢿⡿⣟⣯⣷')
spinner.start()
const tempJson = fse.readJsonSync(pathResolve('package.json'))
// 处理相关依赖
const devJson = fse.readJsonSync(pathResolve('../package.json'))
tempJson.peerDependencies = devJson.peerDependencies
tempJson.dependencies = devJson.dependencies
fse.emptyDirSync(pathResolve('../dist/lib'))
fse.outputJsonSync(pathResolve('../dist/package.json'), tempJson, {
spaces: 2,
})
// 打包处理
const config = require(pathResolve('webpack.config.js'))
// eslint-disable-next-line no-unused-expressions
;(config.output.path = pathResolve('../dist/lib')),
(config.externals = [
...Object.keys(tempJson.peerDependencies),
...Object.keys(tempJson.dependencies),
])
config.plugins = (config.plugins || []).concat([
new webpack.ProgressPlugin((percentage, msg, ...args) => {
spinner.setSpinnerTitle(
chalk.green(
'%s ' + parseInt(percentage * 100) + '% Packing... ' + (args[0] || '')
)
)
if (percentage >= 1) {
spinner.stop()
process.stdout.write('\n')
}
}),
])
webpack(config, (err, stats) => {
if (err) return console.error(err)
if (stats.hasErrors()) {
stats.toJson().errors.forEach((e) => console.error(e))
console.error()
} else {
if (stats.hasWarnings()) {
stats.toJson().warnings.forEach((w) => console.warn(w))
}
console.log(chalk.green('✅ Packing successfully'))
}
})
tsconfog.json
{
"compilerOptions": {
"baseUrl": "../",
"noImplicitAny": true,
"module": "esnext",
"declaration": true,
"declarationDir": "../dist/lib",
"target": "es5",
"jsx": "react-jsx",
"allowJs": true,
"moduleResolution": "node",
"noEmit": false,
"allowSyntheticDefaultImports": true,
"paths": {
"@/*": ["src/*"]
},
},
"include": [
"../src/packages"
]
}
需要修改根目录下 package.json
添加 peerDependencies
{
...
"peerDependencies": {
"react": "^18.1.0",
"react-dom": "^18.1.0"
},
“scripts”: {
...
"publish": "node ./config/package.js"
}
}
现在我们就配置好了,当我们需要打包时候,就可以 执行 npm run publish
即可;
打完包,执行 npm publish dist
即可发布到仓库;