基于Vue CLI 3的webpack配置简解
最近在学习写TypeScript时,tsc编译后ts文件老是报变量占用的错误,后来配置tsconfig.js编译到不同的目录可以了,但是每次更改都要手动编译好麻烦,就想自己配置一个webpack开发环境,之前用脚手架都不清楚具体配置,参考Vue脚手架配置,这篇博文也是基于Vue的配置总结。npm命令 回忆一下我们在使用webpack的时候,打包的时候一般命令都是 webpac...
最近在学习写TypeScript时,tsc编译后ts文件老是报变量占用的错误,后来配置tsconfig.js编译到不同的目录可以了,但是每次更改都要手动编译好麻烦,就想自己配置一个webpack开发环境,之前用脚手架都不清楚具体配置,参考Vue脚手架配置,这篇博文也是基于Vue的配置总结。
npm命令
回忆一下我们在使用webpack的时候,打包的时候一般命令都是 webpack ... 或者是 webpack-dev-server ... 来打包资源,我们在使用Vue脚手架的时候一般使用两个命令,一个是 npm run dev,一个是 npm run build。先来说 npm run命令是个什么东西,每当我们执行npm run命令的时候,就会新建一个shell,他会将当前目录node_modules/.bin加入path变量中,那在package.json中使用scripts来定义脚本,来看一下Vue是怎么配置dev和build的
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js,
"start": "npm run dev",
"build": "node build/build.js"
},
我们在运行npm run dev的时候,可以理解新建shell然后执行了webpack-dev-server *** 命令,关于后边的配置项后面再说。我们看到start中配置了的npm run dev,因为npm run start可以简写成 npm start比较简洁,那我们就可以知道
npm run dev = npm start = npm run start = webapck-dev-server --inline --progress --config build/webpack.dev.conf.js
那么npm run build应该更好理解了,就是执行了 node build/build.js,关于build.js里面做了什么后边再说。想要更详细了解npm可以点击npm scripts 使用指南。
webpack的配置文件
webpack有两种使用方式,终端或Node.js,无论那种方式都需要传递一个配置对象(configuration object),很好的是Vue CLI两种方式都用了,首先来看dev模式下的配置文件。
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --host 0.0.0.0"
webpack-dev-server是在开发过程中使用的,不仅可以启动服务供你访问页面,还能进行模块热替换,本篇只讨论简单配置,因为复杂的我也需学习。对于dev-server有很多选项能控制其行为,一种方式是在命令行后,如上面的--inline、--progress,另一种方式就是在配置文件中体现,关于更多配置项有兴趣请点击开发中 Server。我们自己搭建webpack的时候知道,配置项默认是webpack.config.js,那在dev命令行中 --config的作用是更改了默认配置文件,为当前目录下build/webpack.dev.conf.js。在我们自动搭建的项目中,大家都会看到以下目录
大致先说一下build下每个文件,上文我们说过npm run build就是执行了 node build/build.js,所以我们在输出代码时候执行的就是上图中的build.js文件,webpack.base.conf.js如其名他就是一个基础配置文件,根据用户使用条件不同又加了两个webpack.dev.conf.js开发时的配置文件和webpack.prod.conf.js可以理解成生产配置文件。先说开发中的webpack.base.conf.js
//webpack.base.conf.js 省略的很多配置内容
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.js'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
module: {
rules: [...]
},
node: {
...
},
};
可以看到基础项里面就是我们自己搭建时候写的入口、出口、loader、插件等基础项,
//由于不想篇幅过长,省略了很多不相关的代码
...
const config = require('../config')
const merge = require('webpack-merge')
...
//引入了base.conf文件
const baseWebpackConfig = require('./webpack.base.conf')
const HtmlWebpackPlugin = require('html-webpack-plugin')
...
//看到merge就知道是将后边的配置项和基准baseWebpackConfig合并
const devWebpackConfig = merge(baseWebpackConfig, {
...
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay
? { warnings: false, errors: true }
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
},
plugins: [
...
//使用webpack-dev-server的主要插件
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
...
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
在dev.conf.js中加入了很多webpack-dev-server的配置项,可以看到最开始引入了const config = require('../config') ,我们可以看到在build同级目录下存在一个config(可在上截图中看到),在dev配置文件中引入了这个文件夹,那我们打开它下边的index.js
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': { //代理地址
target: 'http://**.110.130.**:8000', //需要代理的地址
changeOrigin: true, //是否跨域
secure: false,
pathRewrite: {
'^/api': ''
}
}},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080,
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
cacheBusting: true,
cssSourceMap: true
},
build: {
...
}
}
可以看到目录下又dev和build两个选项,那我们在webpack.dev.conf.js中可以看到
host: HOST || config.dev.host,
port: PORT || config.dev.port,
也就是说,在HOST和PORT没有设置的情况下,回去config.dev下取,这也是为什么我们开发中如果需要更改端口,需要更改config/index.js中dev下的host和port,对于各个配置项的作用还是建议大家取webpack官网上看一下。写写感觉篇幅有点长了,在简单说一下build的,其实原理和开发一下,只不过有些配置选项更改了,感觉还要写一个解析配置项的文章?,我们已经知道了npm run build执行的是 node build/build.js 我们先来看一下build.js文件
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, (err, stats) => {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})
这个就直接全粘过来了,之前我们提到过,wenpack又两种执行方式,对于dev来说是执行了shell命令,那对于build来说是执行了node的一种方式
const webpack = require("webpack");
webpack({
// 配置对象
}, (err, stats) => {
if (err || stats.hasErrors()) {
// 在这里处理错误
}
// 处理完成
});
build,js中webpack传入了webpackConfig = require('./webpack.prod.conf'),那么它的配置就是base+prod的merge,通过node的内置对象process将结果输出到控制台,关于配置文件中插件和配置项的作用,如果有机会在进行深入的解读,希望这篇文章对你有所帮助。
在补充一点,不同于webapck会输出可见的文件,webpack-dev-server输出的文件并不可见,江湖传言是在内存当中,编译后的bundle.js你可以通过localhost:8080/bundle.js看到,最好的方式是引入HtmlWebpackPlugin插件,这样你编译后bundle.js就会插入到你的script标签中。我觉得个人对webpack还是只停留在使用阶段,本来标题是详解,后来想想还是改成简解(简单解释?)期望能研究一下更深入有意思对项目有帮助的东西。
更多推荐
所有评论(0)