Badges
tl;dr
vbuild whatever.js --dev
# it just worksDevelop Vue apps with no build configuration until you need.
- Install
- How to use
- Config file
- JavaScript API
- Recipes
- Limitations
- FAQ
- Contributing
- Author
Install
It works with both Yarn(>=0.17) and npm(>=3):
yarn global add vbuild
# You can also install it locally
# yarn add vbuild --devHow to use
The simple way
vbuild init <folder>Then follow the instructions in terminal.
Or manually, populate an entry file, let's say index.js:
import Vue from 'vue'
new Vue({
el: '#app',
render: h => <h1>Hello World!</h1>
})Run app in dev mode:
vbuild index.js --devSo far we get:
- Automatic transpilation and bundling (with webpack and babel/postcss)
- Hot code reloading
- Static file in
./static/will be copied to./dist/
To see how simple it is, check out our official website which is built with vbuild itself.
Build app in production mode (default mode):
vbuild index.jsConfig file
All CLI options and advanced options can be set here:
module.exports = (options, req) => ({
port: 5000
// Other options
})
// Note that you can directly export an object too:
// module.exports = {port: 5000}To use it, you can add --config [path] in CLI arguments. If no path was speified, it defaults to vbuild.config.js.
Shorthand
To set different config for different mode, you may use options.dev like:
module.exports = options => ({
webpack(cfg) {
if (options.dev) {}
else {}
return cfg
}
})To simplify this, we provide a shorthand to do this:
module.exports = {
production: {}, // used in `!options.dev`
development: {} // used in `options.dev`
}The production or development config will be assigned into base config using Object.assign.
Arguments
options
CLI options.
req
The require function but context directory is the path to node_modules/vbuild/lib, which means you can use it to load vbuild's dependencies, like webpack.
Babel
JS files and script tags in single-file components are transpiled by Babel. We only use one preset by default: babel-preset-vue-app.
You can provide custom babel config by setting babel in config file or using .babelrc or setting babel field in package.json.
If you want to use custom babel config file, please set babel in config file to undefined first.
PostCSS
Standalone .css files and style tags in single-file components are transpiled by PostCSS, the only plugin we use by default is autoprefixer, and you can use autoprefixer option
in config file to adjust it, here's the config with default value:
module.exports = {
autoprefixer: {
browsers: ['ie > 8', 'last 4 versions']
}
}You can also set postcss option in config file, when it's an Array or Object, we will prepend autoprefixer plugin to it. You can set autoprefixer: false to disable
this though.
If you want to use PostCSS config file like postcss.config.js or whatever postcss-load-config supports, please set postcss option
in config file to undefined first.
Custom CSS preprocessors
Supported preprocessors: sass scss stylus less, the workflow of CSS is custom css preprocessor -> postcss-loader -> css-loader.
To use a custom CSS preprocessor, you can directly install relevant loader and dependency. For example, to use scss:
yarn add node-sass sass-loader --devCSS modules
To use CSS modules in single-file component, you can set module attribute in <style></style> tag.
To use CSS modules in standalone css files, you can set cssModules to true in config file.
Webpack entry
Type: string Array Object
You can set webpack entry from CLI option or entry property in config file. If it's an array or string, we add it into webpackConfig.entry.client entry, otherwise it will totally override webpackConfig.entry
Hot reloading
By default we add HMR client to client entry, you can change it by:
module.exports = {
hmrEntry: ['other-name']
}Code splitting
We enabled code splitting for vendor code and app code by default in production mode, you can set vendor option to false to disable it. And by default all required modules in node_modules will be split.
Webpack
Mutate webpack config as you wish:
module.exports = options => ({
webpack(webpackConfig) {
if (options.dev) {
// Apply some changes to webpackConfig
}
return webpackConfig
}
})The value of webpack could also be a plain object, this way it will be merged into default webpack config using webpack-merge.
Custom HTML output
Type: Object Array boolean
html-webpack-plugin options, use this option to customize index.html output, default value:
module.exports = {
html: {
title: 'VBuild',
template: path.join(__dirname, '../lib/template.html')
}
}Check out the default template file we use. To disable generating html file, you can set html to false.
Custom output filename
Set custom filename for js css static files:
module.exports = {
filename: {
js: 'index.js',
css: 'style.css',
static: 'static/[name].[ext]'
}
}Extracting CSS
The extract option is true by default in production mode, however you can also set it manually to overrde:
module.exports = {
// always disable extracting css
extract: false
}Define constants at compile time
define is a short-hand to add webpack's DefinePlugin for settings global constants which can be configured at compile time.
module.exports = options => ({
define: {
__DEV__: JSON.stringify(options.dev)
}
})Then use it in your app code:
if (__DEV__) {
// perform something only in development mode a.k.a `--dev`
}The default constants we add is process.env.NODE_ENV. The variables you defined here are only available in app code.
Load env variables
Your project can consume variables declared in your environment as if they were declared locally in your JS files. By default you will have NODE_ENV defined.
There're three way to define env variables:
- CLI options
--env.VARIABLE_NAME xxx envoption in config file.envfile via dotenv
You can use them in index.html and app code:
# .env file
VUE_APP_DESCRIPTION=my awesome projectIn template html file which uses ejs template, you can write:
<meta name="description" content="!!VUE_APP_DESCRIPTION!!" />In app code you need to write full reference of the variable:
const key = process.env.VUE_APP_KEYTo totally disable this, you can set env to false.
Proxy API request
To tell the development server to serve any /api/* request to your API server in development, use the proxy options:
module.exports = {
proxy: 'http://localhost:8080/api'
}This way, when you fetch /api/todos in your Vue app, the development server will proxy your request to http://localhost:8080/api/todos.
We use http-proxy-middleware under the hood, so the proxy option can also be an object:
module.exports = {
proxy: {
'/api/foo': 'http://localhost:8080/api',
'/api/fake-data': {
target: 'http://jsonplaceholder.typicode.com',
changeOrigin: true,
pathRewrite: {
'^/api/fake-data': ''
}
}
}
}Keep in mind that proxy only has effect in development.
Dev server
port
Type: number
Default: 4000
Port of dev server.
host
Type: string
Default: localhost
Host of dev server.
Custom server logic
Perform some custom logic to development server:
module.exports = {
setup(app) {
app.get('/api', (req, res) => {
res.end('This is the API')
})
}
}Custom build process
Insead of letting vbuild run webpack as the build process, you can perform a custom one by using run function in config file:
// For example, run tests with Karma
const Server = require('karma').Server
module.exports = {
run(webpackConfig) {
const server = new Server({
webpack: webpackConfig,
// ...Other karma options
})
server.start()
}
}JavaScript API
You can use vbuild as a Node.js module:
const vbuild = require('vbuild')
const res = vbuild(cliOptions)
//=> console.log(res)
{
webpackConfig, // final webpack config
options, // final options
compiler, // webpack compiler instance
watcher, // in watch mode, webpack watcher
server, // in dev mode, an instance of `http.Server` without calling `.listen`
devMiddleware // in dev mode, the webpack-dev-middleware instance
}
// error catch
try {
vbuild(options)
} catch (err) {
if (err.name === 'AppError') {
// error occurs in starting the compilation
} else {
// other unknown error
}
}Recipes
- Minimize and sourcemaps
- Bundle in CommonJS or UMD format
- Progressive web app
- Electron app
- ESLint
- Deployment
- Analyze bundle size
- Troubleshooting
Limitations
- Server-side rendering: you can generate server bundle though
- Eject webpack config: here's an on-going issue
Feel free to request new features.
FAQ
Is it like Next.js or Nuxt.js?
Yes and no, yes is because they all simplified the process of building a complete web app, while vbuild is more focusing on building single-page app without the server-side, at least it is for now.
Is it like vue-cli?
No, vue-cli is just a boilerplate generator while vbuild is a Webpack wrapper which reduces boilerplate code for you.
Is there a --watch mode?
Sure, you can combine the --watch mode with default mode and --dev mode, when it's combined with --dev mode, it will remove the hot-reloading support.
What are the differences between --watch --dev and production mode?
The default mode is production mode, i.e. without --dev.
--dev mode uses hot reloading by default, when your file does not support hot reloading it fallbacks to live reloading.
--watch can be used with/without -dev flag:
- with
--dev: no dev server, no hot reloading, since you may not need to open browser at all. It only rebuilt when file changes, all other features indevare the same. - without
--dev: like production mode but it rebuilt due to file changes.
What is this inspired by?
Despiting that vbuild predates Next.js create-react-app nwb vue-cli, we're heavily inspired by these projects.
Contributing
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature - Commit your changes:
git commit -am 'Add some feature' - Push to the branch:
git push origin my-new-feature - Submit a pull request :D
Author
vbuild © EGOIST, Released under the MIT License.
Authored and maintained by egoist with help from contributors (
list).
egoistian.com · GitHub @egoist · Twitter @rem_rin_rin