UNPKG

bootstrap-vue

Version:

BootstrapVue, with over 40 plugins and more than 80 custom components, custom directives, and over 300 icons, provides one of the most comprehensive implementations of Bootstrap v4 components and grid system for Vue.js. With extensive and automated WAI-AR

185 lines (159 loc) 6.26 kB
const { resolve } = require('path') // --- Constants --- const RX_UN_KEBAB = /-(\w)/g const RX_HYPHENATE = /\B([A-Z])/g // Path to index file when using bootstrap-vue source code const srcIndex = 'bootstrap-vue/src/index.js' // --- Utility methods --- // Converts PascalCase or camelCase to kebab-case const kebabCase = str => { return str.replace(RX_HYPHENATE, '-$1').toLowerCase() } // Converts a kebab-case or camelCase string to PascalCase const pascalCase = str => { str = kebabCase(str).replace(RX_UN_KEBAB, (_, c) => (c ? c.toUpperCase() : '')) return str.charAt(0).toUpperCase() + str.slice(1) } const pickFirst = (...args) => { for (const arg of args) { if (arg !== undefined) { return arg } } } // --- Main Nuxt.js module --- module.exports = function nuxtBootstrapVue(moduleOptions = {}) { this.nuxt.hook('build:before', () => { // Merge moduleOptions with default const options = { ...this.options.bootstrapVue, ...moduleOptions } // Ensure we have arrays this.options.css = [].concat(this.options.css || []) this.options.build.transpile = [].concat(this.options.build.transpile || []) const bootstrapVueCSS = pickFirst( options.bootstrapVueCSS, options.bootstrapVueCss, options.bvCSS, // Defaults to `true` if no other options provided true ) if (bootstrapVueCSS) { // Add BootstrapVue CSS this.options.css.unshift('bootstrap-vue/dist/bootstrap-vue.css') } const bootstrapCSS = pickFirst( options.bootstrapCSS, options.bootstrapCss, options.css, // Defaults to `true` if no other options provided true ) if (bootstrapCSS) { // Add Bootstrap CSS this.options.css.unshift('bootstrap/dist/css/bootstrap.css') } // Component src prop resolving this.options.build.loaders.vue.transformAssetUrls = { // Nuxt default is missing `poster` for video video: ['src', 'poster'], // Nuxt default is missing image image: 'xlink:href', // Add BootstrapVue specific component asset items 'b-img': 'src', 'b-img-lazy': ['src', 'blank-src'], 'b-card': 'img-src', 'b-card-img': 'src', 'b-card-img-lazy': ['src', 'blank-src'], 'b-carousel-slide': 'img-src', 'b-embed': 'src', // Ensure super supplied values/overrides are not lost ...this.options.build.loaders.vue.transformAssetUrls } // Enable transpilation of `src/` directory this.options.build.transpile.push('bootstrap-vue/src') // Use pre-transpiled or `src/` const usePretranspiled = pickFirst(options.usePretranspiled, this.options.dev, false) if (!usePretranspiled) { // Use bootstrap-vue source code for smaller prod builds // by aliasing 'bootstrap-vue' to the source files this.extendBuild((config, { isServer }) => { if (!config.resolve.alias) { config.resolve.alias = {} } const index = require.resolve(srcIndex) const srcDir = index.replace(/index\.js$/, '') // We prepend a $ to ensure that it is only used for // `import from 'bootstrap-vue'` not `import from 'bootstrap-vue/*'` config.resolve.alias['bootstrap-vue$'] = index // If users are still cherry-picking modules from esm/ or es/ (legacy), // alias them to src/ to prevent duplicate code imports config.resolve.alias['bootstrap-vue/esm/'] = srcDir config.resolve.alias['bootstrap-vue/es/'] = srcDir }) } // Base options available to template const templateOptions = { // Flag if we are tree shaking treeShake: false, icons: !!options.icons } // Specific component and/or directive plugins for (const type of ['componentPlugins', 'directivePlugins']) { const bvPlugins = Array.isArray(options[type]) ? options[type] : [] templateOptions[type] = bvPlugins // Normalize plugin name to `${Name}Plugin` (component) or `VB${Name}Plugin` (directive) // Required for backwards compatibility with old plugin import names .map(plugin => { // Ensure PascalCase name plugin = pascalCase(plugin) // Ensure new naming convention for directive plugins prefixed with `VB` plugin = type === 'directivePlugins' && !/^VB/.test(plugin) ? `VB${plugin}` : plugin // Ensure prefixed with `Plugin` plugin = /Plugin$/.test(plugin) ? plugin : `${plugin}Plugin` return plugin }) // Remove duplicate items .filter((plugin, i, arr) => arr.indexOf(plugin) === i) if (templateOptions[type].length > 0) { templateOptions.treeShake = true } } // Specific components and/or directives for (const type of ['components', 'directives']) { const ComponentsOrDirectives = Array.isArray(options[type]) ? options[type] : [] templateOptions[type] = ComponentsOrDirectives // Ensure PascalCase name .map(item => pascalCase(item)) // Ensure prefixed with `V` .map(item => (type === 'directives' && !/^V/.test(item) ? `V${item}` : item)) // Remove duplicate items .filter((item, i, arr) => arr.indexOf(item) === i) if (templateOptions[type].length > 0) { templateOptions.treeShake = true } } // If tree shaking, and icons requested, add in // the IconsPlugin if not already specified if ( templateOptions.treeShake && templateOptions.icons && templateOptions.componentPlugins.indexOf('IconsPlugin') === -1 && templateOptions.componentPlugins.indexOf('BootstrapVueIcons') === -1 ) { templateOptions.componentPlugins.push('IconsPlugin') } // Add BootstrapVue configuration if present if (options.config && Object.prototype.toString.call(options.config) === '[object Object]') { templateOptions.config = { ...options.config } } // Register plugin, passing options to plugin template this.addPlugin({ src: resolve(__dirname, 'plugin.template.js'), fileName: 'bootstrap-vue.js', options: templateOptions }) }) } module.exports.meta = require('../package.json')