基于webpack4+vue构建一个可以按需引入的UI组件库


按需加载的思想是将所有的模块分成一个个文件,然后通过import导入对应的依赖文件

如果想兼容一些浏览器,或者使用es6+的语法,可以通过webpack对我们的代码解析编译,然后生成一个个bundle文件,那么应该怎么配置webpack呢

依赖环境:windows,  node

1. 使用npm初始化项目

npm init

2. 安装webpack, webpack-cli

npm i webpack webpack-cli -D

3. 编译webpack配置项

  如果对webpack配置不熟悉的,可以移至另一篇文章(//  todo 暂未更新)

  3.1 我们要的结果是多个bundle,可以想到的是一个多入口的配置,多入口配置中如果项目结构不统一,我们需要一个一个手动添加entry,比较麻烦。所以可以规范一下项目结构,让后续的开发变得更方便一些,下面是我的项目结构

  

 

 

   规定好项目结构后,我们就可以按照固定的结构引入entry  

  

 

 

   除此之外,还需要一个总的bundle,支持一次性导入所有功能,所以在src下面新建一个总的入口文件

  

 

 

 

  

 

 

  以上我们的入口就已经完成了,出口可以参考webpack配置

  3.2 接下来前面提到的使用es6+,所以还需要引入babel

npm i @babel/core @babel/preset-env -D

  

 

 

   include为需要babel解析的文件夹下面的js文件,具体参考另一篇文章webpack配置(//  todo 暂未更新),要注意babel插件的版本,如果版本对应不上,会出现一些奇奇怪怪的错误,文章底部会将所有的依赖版本列出

  3.3 以上我们就已经能够解析我们的js文件了,可以运行命令webpack --config your webpack config path 即可生成对应的文件了,恭喜你,这一步已经可以实现一些基础的js类库的按需加载功能了

  3.4 我们想要的是一个UI组件库,所以必定需要css,所以我们还需要为css添加一些配置,老步骤,安装依赖

npm i css-loader scss sass-loader postcss-loader mini-css-extract-plugin -D

  同样我们只想将某一个组件依赖的css引入,而不是所有的css文件都引入,所以也需要对css做一些简单的处理

 

 

  同js一样,css也需要一个固定的文档结构

  

 

  其中base.scss为公共的基础css,index.scss为所有的scss包,task.js为打包scss的配置,

  本文这里使用的是webpack打包scss,但是webpack出口文件是一个js,我们可以想到用mini-css-extract-plugin将css从js抽离出来,但是js包也会保留下来,我们需要的只是css包,怎么删除掉js包呢,

  可以自己写一个简单的webpack插件,将出css之外的包全部过滤掉

  

 

 

 

  task.js内容为:

  

const fs = require('fs')
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const { assetsPath } = require('../build/utils')

// 过滤plugin
function FilterCreatePlugin() {
}
FilterCreatePlugin.prototype.apply = function(compiler) {
    compiler.hooks.shouldEmit.tap('FilterCreatePlugin', (compilation) => {
        let newAssets = {}
        // 理论会生成css/xxx/xx.js的css文件,此处去除
        for (k in compilation.assets) {
            if (/.*\.css$/.test(k)) {
                newAssets[k] = compilation.assets[k]
            }
        }
        compilation.assets = newAssets
        return true;
    });
}
const stylePath = path.resolve(__dirname, './packages')

const css = fs.readdirSync(stylePath)

const entries = css.reduce((_entries, filePath) => {
  const key = filePath.split('.')[0]
  _entries[key] = stylePath + '/' + filePath
  return _entries
}, {})

module.exports = {
  entry: {
    ...entries
  },
  mode: 'production',
  output: {
    path: path.resolve(__dirname, '../lib/css'),
    filename: '[name].js'
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css',
    }),
    new FilterCreatePlugin()
  ]
}

  运行webpack --config ./task.js 我们就能得到自己想要的css文件了,到这里配置基本就已经完成了

  

4. 编译自己的打包命令

"build:theme": "webpack --config ./styles/task.js",
"build": "webpack --config ./build/webpack.build.conf.js && npm run build:theme",

5. 配置npm发布配置

  根目录下添加.npmignore文件,忽略不需要的文件

.DS_Store
node_modules/
dist/
zip/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json
test/
build/
config/
styles/
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
.gitignore
.stylelintrc
.eslintrc
.babelrc
*.sln
**/.idea
**/node_module

配置主入口文件

 

 

6. 上面我们已经可以打包并且发布了,但是如果我们想按需引入的话,需要 import Button from 'xxxxUI/lib/button' ,比较麻烦,而且容易出错,所以这里借助一个babel插件 babel-plugin-component, 并且在.babelrc文件里面添加配置

"plugins": [
    [
      "component",
      {
        "libraryName": "your uiProject name",
        "styleLibraryName": "your css path"
      }
    ]
  ]

 

依赖包版本:

  

"devDependencies": {
    "@babel/core": "^7.11.6",
    "@babel/plugin-proposal-object-rest-spread": "^7.11.0",
    "@babel/plugin-transform-runtime": "^7.11.5",
    "@babel/polyfill": "^7.11.5",
    "@babel/preset-env": "^7.11.5",
    "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0",
    "@vue/babel-preset-jsx": "^1.1.2",
    "@vue/eslint-config-prettier": "^6.0.0",
    "babel-eslint": "^10.1.0",
    "babel-helper-vue-jsx-merge-props": "^2.0.3",
    "babel-loader": "^8.1.0",
    "babel-plugin-component": "^1.1.1",
    "core-js": "^2.6.11",
    "css-loader": "^4.3.0",
    "eslint": "^7.9.0",
    "eslint-config-standard": "^14.1.1",
    "eslint-friendly-formatter": "^4.0.1",
    "eslint-loader": "^4.0.2",
    "eslint-plugin-html": "^6.1.0",
    "eslint-plugin-import": "^2.22.0",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-prettier": "^3.1.4",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.1",
    "eslint-plugin-vue": "^6.2.2",
    "exports-loader": "^1.1.0",
    "file-loader": "^6.1.0",
    "gulp-sass": "^4.1.0",
    "html-webpack-plugin": "^4.5.0",
    "less": "^3.12.2",
    "less-loader": "^7.0.1",
    "mini-css-extract-plugin": "^0.11.2",
    "postcss": "^8.0.8",
    "postcss-loader": "^4.0.2",
    "prettier": "^2.1.2",
    "sass": "^1.26.11",
    "sass-loader": "^10.0.2",
    "stylelint": "^13.7.1",
    "stylelint-config-standard": "^20.0.0",
    "stylelint-order": "^4.1.0",
    "stylus-loader": "^3.0.2",
    "url-loader": "^4.1.0",
    "vue-loader": "^15.3.0",
    "vue-style-loader": "^4.1.2",
    "vue-template-compiler": "^2.6.12",
    "webpack": "^4.44.2",
    "webpack-bundle-analyzer": "^3.9.0",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0",
    "webpack-merge": "^5.1.4"
  }

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM