Mô hình thư mục dự án Vue.js
Một dự án Vue.js sử dụng Webpack thường có cấu trúc thư mục chính:
build/: Tập tin cấu hình Webpackconfig/: Thiết lập môi trườngsrc/: Mã nguồn ứng dụngstatic/: Tài nguyên tĩnh
Tệp build.js
Điểm vào cho lệnh npm run build:
// Kiểm tra phiên bản Node.js và npm
require('./kiem-tra-phien-ban')()
// Thiết lập môi trường sản xuất
process.env.NODE_ENV = 'production'
const loaderHoatAnh = require('ora')
const xoaThuMuc = require('rimraf')
const duongDan = require('path')
const mauChu = require('chalk')
const goiWebpack = require('webpack')
const cauHinhChung = require('../config')
const cauHinhWebpack = require('./webpack.san-pham.conf')
const boTai = loaderHoatAnh('Đang xây dựng sản phẩm...')
boTai.start()
// Xóa thư mục build cũ
xoaThuMuc(duongDan.join(
cauHinhChung.build.assetsRoot,
cauHinhChung.build.assetsSubDirectory
), loi => {
if (loi) throw loi
goiWebpack(cauHinhWebpack, (loi, thongKe) => {
boTai.stop()
if (loi) throw loi
process.stdout.write(thongKe.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n\n')
console.log(mauChu.cyan(' Xây dựng hoàn tất.\n'))
console.log(mauChu.yellow(
' Lưu ý: Tệp cần được phục vụ qua máy chủ HTTP.\n' +
' Mở index.html trực tiếp sẽ không hoạt động.\n'
))
})
})
Tệp kiem-tra-phien-ban.js
Xác minh phiên bản Node.js và npm:
const mauChu = require('chalk')
const kiemTraPhienBan = require('semver')
const cauHinhGoi = require('../package.json')
const lenhHeThong = require('shelljs')
function thucThi(lenh) {
return require('child_process').execSync(lenh).toString().trim()
}
const yeuCauPhienBan = [
{
ten: 'node',
phienBanHienTai: kiemTraPhienBan.clean(process.version),
yeuCau: cauHinhGoi.engines.node
}
]
if (lenhHeThong.which('npm')) {
yeuCauPhienBan.push({
ten: 'npm',
phienBanHienTai: thucThi('npm --version'),
yeuCau: cauHinhGoi.engines.npm
})
}
module.exports = function() {
const canhBao = []
yeuCauPhienBan.forEach(mod => {
if (!kiemTraPhienBan.satisfies(mod.phienBanHienTai, mod.yeuCau)) {
canhBao.push(`${mod.ten}: ${mauChu.red(mod.phienBanHienTai)} → ${mauChu.green(mod.yeuCau)}`)
}
})
if (canhBao.length) {
console.log(mauChu.vang('\nCần cập nhật các thành phần:\n'))
canhBao.forEach(cb => console.log(` ${cb}`))
process.exit(1)
}
}
Cấu hình Webpack cơ bản
const duongDan = require('path')
const tienIch = require('./utils')
const cauHinh = require('../config')
const cauHinhLoaderVue = require('./vue-loader.conf')
function xacDinhDuongDan(ten) {
return duongDan.join(__dirname, '..', ten)
}
module.exports = {
context: duongDan.resolve(__dirname, '../'),
entry: { ungDung: './src/main.js' },
output: {
duongDan: cauHinh.build.assetsRoot,
tenTep: '[name].js',
duongDanCongKhai: process.env.NODE_ENV === 'production'
? cauHinh.build.assetsPublicPath
: cauHinh.dev.assetsPublicPath
},
resolve: {
phanMoRong: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': xacDinhDuongDan('src')
}
},
module: {
quyTac: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: cauHinhLoaderVue
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [xacDinhDuongDan('src'), xacDinhDuongDan('test')]
},
// Quy tắc xử lý hình ảnh, font, media...
]
},
node: {
setImmediate: false,
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
}
Các cấu hình khác
- webpack.dev.conf.js: Cấu hình máy chủ phát triển
- webpack.prod.conf.js: Tối ưu hóa cho sản xuất
- config/index.js: Thiết lập đường dẫn và cờ
- .babelrc: Chuyển đổi ES6+ sang ES5
- package.json: Quản lý phụ thuộc và script
Thư mục mã nguồn
src/assets/: Tài nguyênsrc/components/: Thành phần giao diệnsrc/main.js: Điểm vào chínhApp.vue: Thành phần gốc
Ví dụ main.js
import Vue from 'vue'
import UngDung from './App'
import boDinhTuyen from './bo-dinh-tuyen'
Vue.config.productionTip = false
new Vue({
el: '#app',
router: boDinhTuyen,
components: { UngDung },
template: '<UngDung/>'
})