@TOC
本地环境
node -v // v9.1.0
npm -v // 6.5.0
webpack -v // 4.32.2
webpack-cli -v // 3.3.2
这里需要注意的是webpack4+以后需要单独安装webpack-cli
起步
1.初始化项目
npm init
一直enter生成package.json文件(小技巧:npm init -y 可以免去繁琐的enter)
2.安装依赖
npm i webpack webpack-cli webpack-dev-server --save-dev
想要深入上述依赖请转webpack文档
依赖安装成功接下来就开始动手吧
3.目录文件配置
根目录鼠标右键新建index.html webpack.config.js src文件夹或:
// window
type >webpcak.config.js
type >index.html
md src
//mac 土豪玩家
touch webpcak.config.js
touch index.html
mkdir src
src目录下面新建 main.js
此时目录如下
project/
src/
main.js
webpack.config.js
index.html
package.json
内容如下:
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpack从零搭设</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
// webpack.config.js
const path = require('path');
const webpack = require('webpack');
modul.exports = {}
4.配置index.html及webpack.config.js
首先
main.js修改如下:
// src/main.js
console.log('hello world');
webpack.config.js修改如下:
// webpack.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = { // module.exports commonjs规范
entry: './src/main.js', // 项目入口文件,webpack将从main.js开始,把所有依赖的js都打包
output: {
path: path.resolve(__dirname, './dist'), // 项目的打包后的输出路径 可修改
publicPath: '/dist/', // 通过devServer访问路径 可修改
filename: 'build.js' // 打包后的文件名 可修改
},
devServer: {
historyApiFallback: true, // When using the HTML5 History API, the `index.html` page will likely have to be served in place of any `404` responses
overlay: true //Shows a full-screen overlay in the browser when there are compiler errors or warnings. Disabled by default. If you want to show only compiler errors
},
};
webpack配置里的核心:
- entry: webpack打包的入口(不是代码执行入口);
- output: webpack打包后生成的静态资源文件,最终会被html引用;
- loader: 转化非js文件成webpack能够处理的js文件;对js文件进行加工;
- plugins: 顾名思义---webpack打包过程中辅助插件;
index.html 修改如下 增加引入打包后的js
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpack从零搭设</title>
</head>
<body>
<div id="app"></div>
</body>
<script src="/dist/build.js"></script>
</html>
package.json修改如下:
"scripts": {
"dev": "webpack-dev-server --open --hot",
"build": "webpack --progress --hide-modules"
},
webpack-dev-server会启动一个静态资源web服务器 --hot参数表示启动热更新
重新启动服务
npm run dev
打开控制台可以看到 有输出hello world
5.vue的起步
安装vue
npm install vue --save
修改main.js如下
// src/main.js
import Vue from 'vue';
// import Vue from 'vue/dist/vue.esm.js' // 解决You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build
// console.log('hello world');
var app = new Vue({
el: '#app',
data: {
mess: 'Hello Vue@2.0!'
}
})
此时 修改index.html如下:
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpack从零搭设</title>
</head>
<body>
<div id="app">
{{ mess }}
</div>
</body>
<script src="/dist/build.js"></script>
</html>
重新启动服务
npm run build
npm run dev
此时
查阅资料发现:
vue有两种形式的代码 compiler(模板)模式和runtime模式(运行)
vue模块的package.json的main字段默认为runtime模式, 指向"dist/vue.runtime.common.js"位置。这是vue升级到2.0之后就有的特点。
但此时我们main.js的写法是
// src/main.js
import Vue from 'vue';
// import Vue from 'vue/dist/vue.esm.js' // 解决You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build
// console.log('hello world');
var app = new Vue({
el: '#app',
data: {
mess: 'Hello Vue@2.0!'
}
})
解决方案 一
// src/main.js
//import Vue from 'vue';
import Vue from 'vue/dist/vue.esm.js' // 解决You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build
// console.log('hello world');
var app = new Vue({
el: '#app',
data: {
mess: 'Hello Vue@2.0!'
}
})
因为vue2.0默认的是runtime模式,需要借助如 webpack 的 vue-loader 工具把 .vue 文件编译成 JavaScript代码;
解决方案 二(常规操作)
// webpack.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = { //module.exports commonjs规范
entry: './src/main.js', // 项目的入口文件,webpack会从main.js开始,把所有依赖的js都加载打包
output: {
path: path.resolve(__dirname, './dist'), // 项目的打包文件路径
publicPath: '/dist/', // 通过devServer访问路径
filename: 'build.js' // 打包后的文件名
},
devServer: {
historyApiFallback: true,
overlay: true
},
resolve: { // 修改别名,import Vue from ‘vue’ 这行代码被解析为 import Vue from ‘vue/dist/vue.esm.js
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
};
这个修改和上次是一样的意思,不过相对雅观很多...
解决方案 三
修改main.js的模式
- compiler 模式
// src/main.js
// compiler 模式
new Vue({
el: '#app',
})
2.runtime 模式
//runtime模式
new Vue({
render: h => h(App) // App.vue
}).$mount("#app")
将1换成2,但我们推荐使用方案二;
最后 页面展示如下:
引入css和scss
webpack默认支持的是js的模块化,如果需要其他类型文件也支持模块化开发,则需要引入相应的loader用以解析!
安装相关依赖
npm i node-sass css-loader vue-style-loader sass-loader --save-dev
webpack.config.js 修改如下
// webpack.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = { //module.exports commonjs规范
entry: './src/main.js', // 项目的入口文件,webpack会从main.js开始,把所有依赖的js都加载打包
output: {
path: path.resolve(__dirname, './dist'), // 项目的打包文件路径
publicPath: '/dist/', // 通过devServer访问路径
filename: 'build.js' // 打包后的文件名
},
devServer: {
historyApiFallback: true,
overlay: true
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
module: {
rules: [
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
],
},
{ // scss
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
],
}
]
}
};
此时scss 及 css都能在开发中使用并且模块化引入了
语法转译 ES6 => ES5
引入相关依赖 利用bable转译
npm i babel-core babel-loader babel-preset-env babel-preset-stage-3 --save-dev
其中 babel-preset-stage是不同阶段语法提案的转码规则(共有4个阶段),选装一个,其中0最厉害
npm install --save-dev babel-preset-stage-0
npm install --save-dev babel-preset-stage-1
npm install --save-dev babel-preset-stage-2
npm install --save-dev babel-preset-stage-3
// .babelrc
{
"presets": [
["env", { "modules": false }],
"stage-3"
]
}
同时修改 webpack.config.js
// webpack.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = { //module.exports commonjs规范
entry: './src/main.js', // 项目的入口文件,webpack会从main.js开始,把所有依赖的js都加载打包
output: {
path: path.resolve(__dirname, './dist'), // 项目的打包文件路径
publicPath: '/dist/', // 通过devServer访问路径
filename: 'build.js' // 打包后的文件名
},
devServer: {
historyApiFallback: true,
overlay: true
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
module: {
rules: [
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
],
},
{ // scss
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
],
},
{ // 添加解析js的loader
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
}
]
}
};
此时我们修改main.js尝试使用es6语法
// src/main.js
import Vue from 'vue';
// import Vue from 'vue/dist/vue.esm.js' // 解决You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build
// console.log('hello world');
const say = function () {
return new Promise((resolve, reject) => {
resolve('I am es6');
})
}
var app = new Vue({
el: '#app',
data: {
mess: 'Hello Vue@2.0!'
},
methods: {
updateData() {
say().then((res)=>{
this.mess = res;
});
},
},
created() {
this.updateData();
}
})
此时页面输出效果如下
虽然满足我们使用了,那么接下来我们尝试一下ES7支持与否
main.js修改如下:
import Vue from 'vue';
// import Vue from 'vue/dist/vue.esm.js' // 解决You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build
// console.log('hello world');
const say = function () {
return new Promise((resolve, reject) => {
resolve('I am es7');
})
}
var app = new Vue({
el: '#app',
data: {
mess: 'Hello Vue@2.0!'
},
methods: {
/*updateData() {
say().then((res)=>{
this.mess = res;
});
},*/
async updateData() {
const mess = await say();
this.mess = mess;
}
},
created() {
this.updateData();
}
})
页面展示如下:
此时看到控制台报错
"ReferenceError: regeneratorRuntime is not defined"
查阅相关文章发现, 要想对es7语法进行支持,还需要安装相关依赖进行转译;
这里有两种方案
方案一
npm i --save-dev babel-plugin-transform-runtime
修改.babelrc文件
// .babelrc
{
"presets": [
["env", { "modules": false }],
"stage-3"
],
"plugins": [[ // 参考 //www.greatytc.com/p/7a7f7abcddb5
"transform-runtime",
{
"helpers": false,
"polyfill": false,
"regenerator": true,
"moduleName": "babel-runtime"
}
]]
}
这里顺带解释一下preset与babel的关系:
- preset中已经包含了一组用来转换ES6+的语法的插件,如果只使用少数新特性而非大多数新特性,可以不使用preset而只使用对应的转换插件
- babel默认只转换语法,而不转换新的API,如需使用新的API,还需要使用对应的转换插件或者polyfill
例如,默认情况下babel可以将箭头函数,class等语法转换为ES5兼容的形式,但是却不能转换Map,Set,Promise等新的全局对象,这时候就需要使用polyfill去模拟这些新特性
此时看到页面输出正常:
方案二
全局babel-polyfill
npm i babel-polyfill --save-dev
webpack.config.js修改如下 注意看注释
// webpack.config.js
// entry: './src/main.js', // 项目的入口文件,webpack会从main.js开始,把所有依赖的js都加载打包
entry: ['babel-polyfill', './src/main.js'], // 项目的入口文件,webpack会从main.js开始,把所有依赖的js都加载打包 参考 //www.greatytc.com/p/3b27dfc6785c
此时重新跑项目npm run dev 结果方案一
es6与es7转译部分参考文章
babel-polyfill的几种使用方式
babel的使用
文章最后
项目搭建,缺啥补啥!! 项目完整地址查看@王一诺wlove_c/webpack4.0+vue2.0
2019年6月16日文章更新webpack代理配置
此次更新的原因是在一个技术分享群有同学问到,当时有点懵,webpack都更新到4.34.0了还有同学不会设置代理,所以借助这边文章更新一下代理配置;
安装依赖 webpack-dev-server
npm install webpack-dev-server --save-dev
实际上webpack是通过http-proxy-middleware来作方向代理解决跨域的,详情有兴趣的同学可以自己了解一下
修改配置如下
// webpack.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = { //module.exports commonjs规范
...
devServer: {
historyApiFallback: true,
overlay: true,
proxy: {
'/api': {
target: 'http://localhost:3000', // 接口的域名和端口 如果端口为80则可以不写
pathRewrite: {'^/api' : ''}, // 如果不是以api开头的可以清空
changeOrigin: true, // target是域名的话,需要这个参数,
secure: false, // 默认情况下,不接受运行在 HTTPS 上,且使用了无效证书的后端服务器。如果你想要接受,修改配置如下:
},
},
},
...
};
此时你跑项目的时候 npm run dev 时 你会发现,请求到 /api/users 现在会被代理到请求 http://localhost:3000/api/users。并且不会有跨域问题!不过后端同学要允许跨域或者设置域名白名单喔
更多webpack-dev-server配置可以转@webpack/devserver-proxy
如果你想要nginx作代理的话也是可以滴;详情请转我的另一篇文章@王一诺Eno的文章nginx部署/代理/跨域