webpack基础配置&&单文件组件与vue-loader
参考《Vue,js》实战(梁灏编著)
笔者近期学习Vue.js进阶篇,参考教程流程完成webpack、vue、babel等相关配置时,发现教程的版本较之目前版本有较大差异,因而产生大量BUG,经过一系列百度并参考官方文档,整理出整套webpack4基础配置及vue-loader、babel7相关操作流程。
git代码
1.新建demo文件夹 初始化
npm init
2.安装webpack webpack-cli webpack-dev-server
npm i webpack webpack-cli webpack-dev-server -D
/*i 是install的简写,-D 是 --save-dev的简写*/
3.在根目录创建webpack.config.js
var config = {
};
module.exports=config;
4.在package.json的scripts里增加一个快速启动webpack-dev-server服务的脚本
"dev":"webpack-dev-server --open --config webpack.config.js",
5.在demo目录下新建一个空的main.js作为入口的文件,然后在webpack.config.js中进行入口和输出的配置
var path = require('path');
var config = {
entry:{
main: './main'
},
output:{
path: path.resolve(__dirname,'./dist'),
publicPath: '/dist/',
filename: 'main.js'
},
};
module.exports=config;
6.在demo目录下,新建一个index.html作为我们SPA的入口
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack APP</title>
</head>
<body>
<div id="app">
Hello World.
</div>
<script type="text/javascript" src="/dist/main.js"></script>
</body>
</html>
7.在终端执行下面的命令,就会在浏览器中打开页面了
npm run dev
8.打开demp/main.js文件,添加一行JavaScript代码来修改页面的内容
document.getElementById('app').innerHTML='Hello webpack.';
/*webpack-dev-server的热更新功能*/
9.打包 .\node_modules.bin\webpack
在package.json的scripts里增加一个快速启动打包服务的脚本 "start":"webpack"
10.现在要写一些CSS样式,就要用到style-loader和css-loader。(Loaders:加载器)
npm install css-loader --save-dev
npm install style-loader --save-dev
11.安装完成后,在webpack.config.js文件里配置Loader,增加对.css文件的处理:
var path = require('path');
var config = {
entry:{
main: './main'
},
output:{
path: path.resolve(__dirname,'./dist'),
publicPath: '/dist/',
filename: 'main.js'
},
module:{
rules:[
{
test:/\.css$/,
use:[
'style-loader',
'css-loader'
]
}
]
},
};
module.exports=config;
12.新建style.css文件 并在main.js中导入
style.css
#app{
font-size: 24px;
color: #f50;
}
main.js
import './style.css'
document.getElementById('app').innerHTML='Hello webpack.';
13.重新执行npm run dev命令
14.使用extract-text-webpack-plugin插件 把散落在各地的css提取出来,并生成一个main.css文件,最终在index.html里通过的形式加载
npm install –save-dev extract-text-webpack-plugin@next
15 在配置文件中导入插件,并改写loader的配置
<link rel="stylesheet" type="text/css" href="/dist/main.css">
webpack.config.js
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var config = {
entry:{
main: './main'
},
output:{
path: path.resolve(__dirname,'./dist'),
publicPath: '/dist/',
filename: 'main.js'
},
module:{
rules:[
{
test:/\.css$/,
use:ExtractTextPlugin.extract({
use:'css-loader',
fallback:'style-loader'
})
}
]
},
plugins:[
//重命名提取后的css文件
new ExtractTextPlugin("main.css")
]
};
module.exports=config;
单文件组件与vue-loader
16.使用.vue文件需要先安装vue-loader、vue-style-loader等加载器并做配置,因为要使用ES6语法,还需要安装babel和babel-loader等加载器。
npm install --save vue
npm install --save-dev vue-loader
npm install --save-dev vue-style-loader
npm install --save-dev vue-template-compiler
npm install --save-dev vue-hot-reload-api
cnpm i @babel/core babel-loader @babel/plugin-transform-runtime -D
cnpm i @babel/preset-env @babel/plugin-proposal-class-properties @babel/runtime -D
17.修改配置文件webpack.config.js来支持对.vue文件及ES6的解析
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
var config = {
entry:{
main: './main'
},
output:{
path: path.resolve(__dirname,'./dist'),
publicPath: '/dist/',
filename: 'main.js'
},
module:{
rules:[
{
test:/\.vue$/,
loader:'vue-loader',
options:{
loaders:{
css: ExtractTextPlugin.extract({
use:'css-loader',
fallback:'vue-style-loader'
})
}
}
},
{
test:/\.js$/,
loader:'babel-loader',
exclude:/node_modules/
},
{
test:/\.css$/,
use:ExtractTextPlugin.extract({
use:'css-loader',
fallback:'style-loader'
})
}
]
},
plugins:[
new ExtractTextPlugin("main.css"),
new VueLoaderPlugin()
]
};
module.exports=config;
18.在demo目录下新建一个名为.babelrc的文件,并写入babel的配置。
{
"presets": ["@babel/preset-env"],
"plugins": ["@babel/plugin-transform-runtime","@babel/plugin-proposal-class-properties"]
}
19.新建一个app.vue文件
<template>
<div>Hello {{name}}</div>
</template>
<script>
export default {
data(){
return {
name:'Vue.js'
}
}
}
</script>
<style scoped>
div{
color: #f60;
font-size: 24px;
}
</style>
20.在入口main.js中使用它
import './style.css'
//导入Vue框架
import Vue from 'vue';
//导入app.vue组件
import App from './app.vue';
//创建Vue根实例
new Vue({
el:'#app',
render: h=> h(App)//ES6语法
})
21.执行命令npm run dev,第一个Vue工程就跑起来了。
22.在demo目录下再新建两个文件,title.vue和button.vue
//title.vue
<template>
<h1>
<a :href="'#' + title">{{title}}</a>
</h1>
</template>
<script>
export default {
props:{
title:{
type: String
}
}
}
</script>
<style scoped>
h1 a{
color:#3399ff;
font-size: 24px;
}
</style>
//button.vue
<template>
<button @click="handleClick" :style="styles">
<slot></slot>
</button>
</template>
<script>
export default {
props:{
color:{
type: String,
default:'#00cc66'
}
},
computed:{
styles(){
return{
background: this.color
}
}
},
methods:{
handleClick(e){
this.$emit('click',e);
}
}
}
</script>
<style scoped>
button{
border: 0;
outline: none;
color: #fff;
padding: 4px 8px;
}
button:active{
position: relative;
top: 1px;
left: 1px;
}
</style>
//app.vue
<template>
<div>
<v-title title="Vue组件化"></v-title>
<v-button @click="handleClick">点击按钮</v-button>
</div>
</template>
<script>
//导入组件
import vTitle from './title.vue';
import vButton from './button.vue';
export default {
components:{
vTitle,
vButton
},
data(){
return {
name:'Vue.js'
}
},
methods:{
handleClick(e){
console.log(e);
}
}
}
</script>
打开浏览器,如果已经正确渲染出了这两个组件,那么恭喜你,已经进入Vue.js的高级领域啦!
用于生产环境
1.我们先对webpack进一步配置,来支持更多常用的功能。
安装url-loader和file-loader来支持图片、字体等文件:
npm install --save-dev url-loader
npm install --save-dev file-loader
{
test :/\.(gif|jpg|png|woff|svg|eot|ttf)\??.*$/,
loader: 'url-loader?limit=1024'
}
<template>
<div>
<v-title title="Vue组件化"></v-title>
<v-button @click="handleClick">点击按钮</v-button>
<p>
<img src="images/image.jpg" style="width:200px;">
</p>
</div>
</template>
2.打包
npm install --save-dev webpack-merge
npm install --save-dev html-webpack-plugin
//教程错误:Error: webpack.optimize.UglifyJsPlugin has been removed, please use config.optimizat
运行 npm install --save-dev uglifyjs-webpack-plugin 安装uglifyjsPlugin
3.在package.json中,再加入一个build的快捷脚本用来打包
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --open --config webpack.config.js",
"build": "webpack --progress --hide-modules --config webpack.prod.config.js"
}
4.在demo目录下再新建一个用于生产环境的配置文件webpack.prod.config.js
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var {merge} = require('webpack-merge');
var webpackBaseConfig = require('./webpack.config.js');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
//清空基本配置的插件列表
webpackBaseConfig.plugins=[];
module.exports = merge(webpackBaseConfig,{
output:{
publicPath: '/dist/',
//将入口文件重命名为带有20位hash值的唯一文件
filename: '[name].[hash].js'
},
plugins:[
new ExtractTextPlugin({
//提取ccss,并重命名为带有20位hash值的唯一文件
filename: '[name].[hash].css',
allChunks: true
}),
//定义当前node环境为生产环境
new webpack.DefinePlugin({
'process.env':{
NODE_ENV:'"production"'
}
}),
//提取模板,并保存入口html文件
new HtmlWebpackPlugin({
filename: '../index_prof.html',
template: './index.ejs',
inject: false
}),
new VueLoaderPlugin()==webpack4插件==
],
//压缩js==与教程有所区别==
//npm install --save-dev uglifyjs-webpack-plugin
optimization:{
minimizer:[
new UglifyJsPlugin({
uglifyOptions:{
output:{
comments: false
},
warnings: false==处理报错==
}
})
]
}
});
5.模板index.ejs动态设置了静态资源的路径和文件名
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack App</title>
<link rel="stylesheet" href="<%= htmlWebpackPlugin.files.css[0] %>">
</head>
<body>
<div id="app"></div>
<script type="text.javascript" src="<%= htmlWebpackPlugin.files.js[0] %>"></script>
</body>
</html>