Webpack之打包library

0. 目录结构

在这里插入图片描述

src 目录下的一级文件夹,带有index.jx文件的,表示一级组件,一级组件下的文件夹中包含index.jsx文件的,表示二级组件,一级组件和二级组件都会被单独打包成js文件,例如Demo1打包后会生成一下文件结构:
在这里插入图片描述

1. 依赖文件

/package.json

{
    
    
  "name": "webpack-library",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    
    
    "dev": "webpack-dev-server --config ./scripts/dev.js",
    "build": "node ./scripts/build.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    
    
    "@babel/core": "^7.11.6",
    "@babel/plugin-proposal-class-properties": "^7.13.0",
    "@babel/plugin-syntax-jsx": "^7.10.4",
    "@babel/plugin-transform-runtime": "^7.11.5",
    "@babel/preset-env": "^7.11.5",
    "@babel/preset-react": "^7.10.4",
    "babel-loader": "^8.1.0",
    "babel-plugin-css-modules-transform": "^1.6.2",
    "clean-webpack-plugin": "^3.0.0",
    "copy-webpack-plugin": "^9.0.1",
    "css-loader": "^5.2.0",
    "css-minimizer-webpack-plugin": "^1.3.0",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^5.3.2",
    "mini-css-extract-plugin": "^1.4.0",
    "node-sass": "^4.12.0",
    "postcss-loader": "^6.1.1",
    "postcss-preset-env": "^6.7.0",
    "sass-loader": "^7.3.1",
    "webpack": "^5.48.0",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.2"
  },
  "dependencies": {
    
    
    "axios": "^0.21.1"
  },
  "browserslist": {
    
    
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.01%",
      "not dead",
      "npt op_mini all"
    ]
  }
}

2. 配置

2.1 webpack.config.js 配置

const {
    
     CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

module.exports = {
    
    
  entry: '',
  mode: 'production',
  output: {
    
    
    path: '',
    filename: '[name].js',
    library: 'library',
    libraryTarget: 'umd',
    libraryExport: 'default',
    globalObject: 'this'
  },
  module: {
    
    
    rules: [
      {
    
    
        test: /\.js|jsx$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      },
      {
    
    
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
    
    
            loader: 'css-loader',
            options: {
    
    
              sourceMap: true,
            }
          },
          {
    
    
            loader: 'postcss-loader',
            options: {
    
    
              sourceMap: true,
              postcssOptions: {
    
    
                plugins: [
                  require('postcss-preset-env')
                ]
              }
            }
          },
          {
    
    
            loader: 'sass-loader',
            options: {
    
    
              sourceMap: true,
            }
          }
        ],
        exclude: /node_modules/
      },
      {
    
    
        test: /\.(png|svg|jpg|gif|woff|woff2|eot|ttf|otf)$/,
        use: {
    
    
          loader: 'file-loader',
          options: {
    
    
            limit: 500000,
            outputPath: 'images'
          }
        },
        exclude: /node_modules/
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({
    
    
      filename: 'css/[name].css'
    }),
  ],
  optimization: {
    
    
    minimize: true,
    minimizer: [new CssMinimizerPlugin({
    
    })],
    // splitChunks: {
    
    
    //     cacheGroups: {
    
    
    //         commons: {
    
    
    //             name: "commons",
    //             chunks: "initial",
    //             minChunks: 2
    //         }
    //     }
    // }
  },
  resolve: {
    
    
    extensions: ['*', '.js', '.jsx']
  }
};

2.2 .babelrc

{
    
    
  "presets": [
    [
      "@babel/preset-env",
      {
    
    
        "modules": false,
        "useBuiltIns": "usage",
        "corejs": "2.6.10",
        "targets": ">0.2%, not dead, Firefox >= 52, IE >= 8"
      }
    ],
    "@babel/preset-react"
  ],
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
    
    
        "helpers": false,
        "regenerator": true
      }
    ],
    "@babel/plugin-proposal-class-properties"
  ],
  "ignore": [
    "node_modules/**"
  ]
}

2.3 build.js

分别打包多个组件。

const path = require('path');
const fs = require('fs');
const webpackConfig = require('./webpack.config');
// 入口文件配置
const config = require('../src/config');
const {
    
     webpack } = require('webpack');

/**
 * 判断文件是否存在
 * @param {String} path 文件路径
 */
const isExist = (path) => {
    
    
  try {
    
    
    return fs.existsSync(path);
  }
  catch (e) {
    
    
    return false;
  }
}

/**
 * 进行webpack编译
 * @param {Array} entryArr 入口文件夹名称
 * @param {Object} config webpack配置
 */
const startCompile = (entryArr= [], config = {
     
     }) => {
    
    

  console.time('[webpack finished]: totalTime ');
  entryArr.forEach(dirName => {
    
    
    let entry = {
    
    };
    const dirPath = path.resolve(__dirname, `../src/${
      
      dirName}`);
    const indexPath = path.resolve(dirPath, './index.js');

    console.log(`[webpack compiling]: ${
      
      dirPath}`);
    console.time(`[webpack compile]: ${
      
      dirName}`);

    try {
    
    
      if (isExist(dirPath) && isExist(indexPath)) {
    
    
        const components = fs.readdirSync(dirPath);
        for (let i = 0; i < components.length; i++) {
    
    
          const comp = components[i];
          const compPath = path.resolve(dirPath, `${
      
      comp}/index.jsx`);
          if (isExist(compPath)) entry = {
    
     ...entry, [comp]: compPath};
        }
        // 入口
        entry = {
    
     ...entry, index: indexPath };
        // console.log('entry:', entry);
        // 出口
        output = {
    
    
          ...webpackConfig.output,
          path: path.resolve(__dirname, `../dist/${
      
      dirName}/lib`),
          library: dirName
        };
        webpackConfig.entry = entry;
        webpackConfig.output = output;
        // 编译
        webpack(config, function (err, stats) {
    
    
          // webpack 配置错误
          if (err) {
    
    
            console.error('[webpackConfig error]', err.defaults);
            return ;
          }
          // webpack编译错误
          if (stats.hasErrors()) {
    
    
            const info = stats.toJson();
            console.error(`[webpack error]: ${
      
      dirPath}`);
            console.error(info.errors);
          }
          // webpack编译警告
          // if (stats.hasWarnings()) {
    
    
          //   const info = stats.toJson();
          //   console.error(`[webpack warning]: ${dirPath}`);
          //   console.error(info.warnings);
          // }
        })
      }
    }
    catch (e) {
    
    
      console.error(e);
    }
    finally {
    
    
      console.timeEnd(`[webpack compile]: ${
      
      dirName}`);
    }
  });
  console.timeEnd('[webpack finished]: totalTime ');
}

startCompile(config.entry, webpackConfig);

2.4 config.js

入口文件配置

module.exports = {
    
    
  entry: ['demo1', 'demo2', 'demo3']
}

2.5 dev.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const copyWebpackPlugin = require('copy-webpack-plugin');
const commonWebpackConfig = require('./webpack.config');

const devWebpackConfig = {
    
    
  mode: 'development',
  devtool: "inline-source-map",
  devServer: {
    
    
    contentBase: path.join(__dirname, "../build"),
    compress: true,
    port: 9999,
    hot: true,
    open: true
  },
  entry: path.resolve(__dirname, '../src/test/index.jsx'),
  output: {
    
    
    filename: 'js/bundle[hash].js',
    path: path.resolve(__dirname, '../build'),
    publicPath: '/'
  }
}

const webpackConfig = {
    
    
  ...commonWebpackConfig,
  ...devWebpackConfig,
  plugins: [
    ...commonWebpackConfig.plugins,
    new HtmlWebpackPlugin({
    
    
      title: '测试',
      template: path.resolve(__dirname, '../public/index.html'),
      filename: 'index.html',
      inject: 'body',
      minify: false
    }),
    // 复制public中的静态文件
    new copyWebpackPlugin({
    
    
      patterns: [
        {
    
    
          from: path.resolve(__dirname, '../public'),
          to: path.resolve(__dirname, '../build'),
          globOptions: {
    
    
            dot: true,
            gitignore: true,
            ignore: ["**/index.html"],
          }
        }
      ]
    })
  ]
};

module.exports = webpackConfig;

3. 发布

发包流程:https://blog.csdn.net/qq_36968599/article/details/114043965

猜你喜欢

转载自blog.csdn.net/qq_36968599/article/details/119352231