webpack4+加vue2+从零开始搭设vue项目

@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


控制台输出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

此时


控制台报错,页面也未显示hello Vue!

查阅资料发现:
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的模式

  1. compiler 模式
// src/main.js
// compiler 模式
new Vue({
  el: '#app',
})

2.runtime 模式

//runtime模式
new Vue({
render: h => h(App)  // App.vue
}).$mount("#app")

将1换成2,但我们推荐使用方案二;

最后 页面展示如下:


hello Vue@2.0

引入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();
  }
})

此时页面输出效果如下


I am es6

虽然满足我们使用了,那么接下来我们尝试一下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();
  }
})

页面展示如下:


ES7测试

此时看到控制台报错

"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去模拟这些新特性

此时看到页面输出正常:


ES7正常
方案二

全局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代理配置

此次更新的原因是在一个技术分享群有同学问到\color{red}{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部署/代理/跨域

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,082评论 5 464
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,231评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,047评论 0 327
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,977评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,893评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,014评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,976评论 3 388
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,605评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,888评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,906评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,732评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,513评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,980评论 3 301
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,132评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,447评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,027评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,232评论 2 339

推荐阅读更多精彩内容