搭建基于webpack4.0的vue项目
npm install webpack -g
npm install webpack-cli -g
cd webpack-vue
npm init -y
安装 vue webpack webpack-cli webpack-dev-server
npm install --save vue
npm install --save-dev webpack webpack-cli webpack-dev-server
在根目录下新建入口文件index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Webpack-Vue</title>
</head>
<body>
<script src="/dist/build.js"></script>
</body>
</html>
在根目录下创建 wepback.config.js
//webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports ={
};
新建src文件夹目录,在src下新建main.js,此时目录结构
webpack-vue
├── node_modules 依赖安装目录
├── src #前端项目源码目录
│ └────main.js #项目的核心文件
├── index.html #首页入口文件,你可以添加一些 meta 信息或同统计代码啥的
├── package-lock.json #项目配置文件
├── package.json #项目配置文件
└── README.md #项目的说明文档,markdown 格式
└── webpack.config.js #项目配置文件
src目录下新建一个utils.js
//utils.js
module.exports = function say(){
console.log('hello world!');
}
main.js
//main.js
var say = require('./utils');
say();
webpack.config.js
//webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports ={
entry: './src/main.js', //项目的入口文件,webpack会从main.js开始,把所有依赖的js都加载打包
output:{
path: path.resolve(__dirname, './dist'), //项目的打包文件路径
publicPath: '/dist/', //通过devServer 访问路径
filename: 'build.js' //打包后的文件名
},
devServer: {
historyApiFallback: true, //historyApiFallback设置为true那么所有的路径都执行index.html。
overlay:true, //将错误显示在html之上
port: 8282
}
};
在package.json中的scripts对象中添加如下命令,用以开启本地服务器:
{
...
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"server": "webpack-dev-server --open"
},
...
}
运行
npm run server
可以在http://localhost:8282/的控制台 console栏目 看到 hello world!
在package.json
{
...
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack --mode development",
"server": "webpack-dev-server --open"
},
...
}
运行
npm run dev
, 可以看到dist
下有一个build.js
文件
- webpack默认不支持转码es6,但是import export这两个语法却单独支持。所以我们可以改写前面的模块化写法
//utils.js
export default function say(){
console.log('hello world!');
}
main.js
//main.js
import Vue from 'vue';
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Webpack-Vue</title>
</head>
<body>
<div id="app">
{{message}}
</div>
<script src="/dist/build.js"></script>
</body>
</html>
webpack.config.js
//webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports ={
...
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
}
};
- webpack默认只支持js的模块化,如果需要把其他文件也当成模块引入,就需要相对应的loader解析器
npm install --save-dev node-sass css-loader vue-style-loader sass-loader
webpack.config.js
//webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports ={
...
resolve: {
...
},
module: {
rules: [
{ //匹配后缀名为css的文件,然后分别用css-loader,vue-style-loader去解析
//解析器的执行顺序是从下往上(先css-loader再vue-style-loader)
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
],
},
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
],
},
{
test: /\.sass$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader?indentedSyntax'
],
}
]
}
};
- 注意:因为我们这里用vue开发,所以使用vue-style-loader,其他情况使用style-loader
- css-loader使得我们可以用模块化的写法引入css,vue-style-loader会将引入的css插入到html页面里的style标签里
common.scss
body{
background:#fed;
}
main.js
import './style/common.scss';
- ES6的语法大多数浏览器依旧不支持,bable可以把ES6转码成ES5语法,这样我们就可以大胆的在项目中使用最新特性了
npm --save-dev babel-core babel-loader babel-preset-env babel-preset-stage-3
//.babelrc
{
"presets": [
["env", {"modules": false}],
"stage-3"
]
}
webpack.config.js添加一个loader
//webpack.config.js
var path = require('path');
var webpack = require('webpack');
module.exports ={
...
module: {
rules: [
{ //匹配后缀名为css的文件,然后分别用css-loader,vue-style-loader去解析
//解析器的执行顺序是从下往上(先css-loader再vue-style-loader)
test: /\.css$/,
use: [
...
],
},
{
test: /\.scss$/,
use: [
...
],
},
{
test: /\.sass$/,
use: [
...
],
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude:/node_modules/ //exclude表示忽略node_modules文件夹下的文件,不用转码
}
]
}
};
utils.js
//utils.js
export default function getData(){
return new Promise((resolve, reject) =>{
resolve('ok');
})
}
main.js
import getData from './utils';
import Vue from 'vue';
import './style/common.scss';
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
methods: {
async fetchData() {
const data = await getData();
this.message = data;
}
},
created() {
this.fetchData();
}
});
- 把图片当成模块引入
npm install --save-dev file-loader
webpack.config.js添加一个loader
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
main.js
//main.js
import getData from './utils';
import Vue from 'vue';
import './style/common.scss';
Vue.component('my-component',{
template: '<img :src="url" />',
data() {
return {
url: require('./img/logo.png')
}
}
})
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
methods: {
async fetchData(){
const data = await getData();
this.message = data;
}
},
created(){
this.fetchData();
}
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Webpack-Vue</title>
</head>
<body>
<div id="app">
{{message}}
<my-component />
</div>
<script src="/dist/build.js"></script>
</body>
</html>
- 在此刻我在重新 npm run server 的时候我报了一个如下的错误,应该是由版本引起的
npm install --save-dev babel-loader@7
Couldn't find preset "@babel/preset-env" relative to directory
- 原因:
webpack.config.js
中 exclude:'/node_modules/' 多了 【' '】单引号 - 解决问题:
exclude: /node_modules/
- 在前面的例子里,我们使用Vue.component来定义全局组件
- 在实际项目里,更推荐使用单文件组件
npm install --save-dev vue-loader vue-template-compiler
添加一个loader:
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders:{
'scss': [
'vue-style-loader',
'css-loader',
'sass-loader'
],
'sass': [
'vue-style-loader',
'css-loader',
'sass-loader?indentedSyntax'
]
}
}
}
在
src
目录下新建一个APP.vue
<template>
<div id="app">
<h1>{{ msg }}</h1>
<img src="./img/logo.png" alt="" />
<input type="text" v-model="msg" />
</div>
</template>
<script>
import getData from './utils';
export default {
name: 'app',
data(){
return {
msg: 'Welcome to Your Vue.js!'
}
},
created(){
this.fetchData();
},
methods: {
async fetchData(){
const data = await getData();
this.msg = data;
}
}
}
</script>
<style lang="scss">
#app{
font-family: Arial, Helvetica, sans-serif;
h1{
color:#cc3333;
}
}
</style>
main.js
//main.js
import Vue from 'vue';
import App from './App.vue';
import './style/common.scss';
new Vue({
el: '#app',
template: '<App/>',
components: { App }
})
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Webpack-Vue</title>
</head>
<body>
<div id="app"></div>
<script src="/dist/build.js"></script>
</body>
</html>
报错: vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.
-
分析:
- 参考官方文档 https://vue-loader.vuejs.org/migrating.html#a-plugin-is-now-required
- Vue-loader在15.*之后的版本都是 vue-loader的使用都是需要伴生 VueLoaderPlugin的,
-
解决:
- webpack.config.js中加入:
//webpack.config.js
var path = require('path');
var webpack = require('webpack');
var VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports ={
entry: './src/main.js', //项目的入口文件,webpack会从main.js开始,把所有依赖的js都加载打包
output:{
...
},
devServer: {
...
},
resolve: {
...
},
plugins: [
//make sure to include the plugin for the magic
new VueLoaderPlugin()
],
module: {
...
}
};
- 最后发现控制台会报一个错误regeneratorRuntime is not defined,因为我们没有安装babel-polyfill
npm install --save-dev babel-polyfill
- 然后修改webpack.config.js的入口
entry: ['babel-polyfill', './src/main.js']
App.vue:
created(){
this.fetchData();
console.log('33333');
}
-
console栏目中 打印出 '33333';
-
进入的是打包后的build.js,我并不知道是在哪个组件里写的,这就造成了调试困难
这时就要修改webpack.config.js
module.exports = {
entry: ['babel-polyfill', './src/main.js'],
// 省略其他...
devtool: '#eval-source-map'
};
- 我们试着npm run dev 打包一下文件
- 会发现 build.js会非常大,有1.9M多
clean-webpack-plugin---清除文件
npm install --save-dev clean-webpack-plugin
webpack.production.config.js
//webpack.config.js
var path = require('path');
var webpack = require('webpack');
var VueLoaderPlugin = require('vue-loader/lib/plugin');
var { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports ={
...
devtool: 'none',//注意修改了这里,这能大大压缩我们的打包代码
module: {
...
},
plugins: [
new CleanWebpackPlugin(),
new webpack.BannerPlugin('版权所有,翻版必究'),
//make sure to include the plugin for the magic
new VueLoaderPlugin()
]
};
在package.json中的script下面写:
"build": "set NODE_ENV=production && webpack --config ./webpack.production.config.js --progress",