按需加載的思想是將所有的模塊分成一個個文件,然后通過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" }