我們?cè)谏弦黄恼乱呀?jīng)介紹過使用rollpkg進(jìn)行打包發(fā)布,這篇我們介紹一下如何使用webpack進(jìn)行打包,畢竟在工作中,使用webpack的頻率更高;
首先初始化項(xiàng)目
npx create-react-app [project-name] --template typescript
在src/文件夾新建 /packages 文件夾,也可以為其他名字,這個(gè)就是用來(lái)要發(fā)布的 npm包 內(nèi)容;
安裝 webpack 及 ts 相關(guān)依賴
npm install webpack ts-loader
- 添加 webpack 打包相關(guān)內(nèi)容
-
在根目錄新建 config 文件夾
image.png
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 發(fā)布地址
}
}
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'))
// 處理相關(guān)依賴
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"
}
}
現(xiàn)在我們就配置好了,當(dāng)我們需要打包時(shí)候,就可以 執(zhí)行 npm run publish 即可;
打完包,執(zhí)行 npm publish dist 即可發(fā)布到倉(cāng)庫(kù);
