基於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