Webpack + vue 搭建

正文开始

 WebPack(前往官网)可以看做是模块打包机:直接分析项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。Gulp/Grunt是一种能够优化前端的开发流程的工具。<br /><br />   Grunt和Gulp的工作方式是:在一个配置文件中,指明对某些文件进行编译,组合,压缩等任务的具体步骤,运行之后自动逐步完成设定的任务。<br /><br />   而WebPack是一种模块化的方案,通过给定的主文件(如:index.js)使用不同的loaders处理项目的所有依赖文件,最后打包为一个浏览器可识别的JavaScript文件。<br /><br /> 其实两者并不具备太多可比性,grunt/gulp 在配置上比较简单,环境搭建更容易实现;而webpack的处理速度更快更直接,能打包更多不同类型的文件。<br />开始使用webpack<br /><br />相关的技术:webpack@2,vue@1,vue-router@0.7,vuex@1<br /><br />目录结构:<br /><br /><ul><br /><li>config全局变量<br /><li>dist编译后的项目代码</li><br /><li>src项目代码<br /><ul> <li> apis api封装<br /><br /><li>components Vue组件<br /><li>libs js工具类<br /><li>router 路由<br /><li>index.js 路由对象<br /><li>routes.js 路由配置<br /><li>store Vuex的store<br /><li>modules vuex模块<br /><li>types.js type管理<br /><li>styles css样式<br /><li>views 页面组件<br /><li>main.js vue入口文件</ul><br /><br /><li>webpack.config Webpack各种环境的配置文件<br /><li>package.json<br /></ul><br />step1   初始化项目 ---- Webpack 使用npm安装<br /><br />1.创建项目文件夹, npm init -y 创建 package.json<br /><br />2.项目根目录下建立src和dist文件夹,分别用来存放项目源码和webpack编译后的代码<br />step2   入口文件--- 简单跑一下<br /><br />1.在根目录下直接建立一个index.html,作为页面的入口文件<br /><br /><!DOCTYPE html><br /><html lang="en"><br /><head><br /><meta charset="UTF-8"><br /><title>Demo</title><br /></head><br /><body><br />  <div id="app">{{message}}</div>  <!-- Vue模板入口 --><br />  <script src="dist/main.js"></script><br /></body><br /></html><br /><br />2.在src下建立一个main.js,作为Vue的入口文件<br /><br />// require的语法是Commonjs的,webpack自身可以实现直接使用<br />// es6的语法需要依赖babel哦<br />const Vue = require('vue')<br />new Vue({<br />el: '#app',<br />data: {<br />message: 'Hello Vue.js!'<br />      }<br />})<br /><br />3.安装模块: vue npm install vue@1 --save ; webpack npm install webpack --save-dev(在本地安装)<br /><br />本地安装的webpack 需要在package.json的 scripts 配置中添加运行脚本<br /><br />      <br />"scripts": {<br />"test": "echo "Error: no test specified" && exit 1",<br />"dev": "webpack src/main.js dist/main.js"  // <---自行添加,指定运行的文件 **webpack [入口文件] [出口文件]**<br /> },<br /><br />运行npm run dev,再用浏览器打开index.html就能看到效果了:<br /><br />Hello Vue.js!<br /><br />全局安装webpack npm install -g webpack 则无需指定脚本~<br /><br />step3   编写webpack配置文件 !!<br /><br />在上一步中专门指定了webpack运行脚本去运行指定的文件,但实际开发中,对于不同环境的大型项目/系统开发显然是不满足的。因此创建一个文件专门存放webpack配置~<br /><br />1.在根目录下创建 webpack.config 文件夹来存放webpack的配置文件;<br /><br />2.在上面的目录下首先创建一个base.js文件来存在一些公共环境下的配置文件(例如loaders的配置)<br /><br />const path = require('path')<br />const root = path.resolve(__dirname, '..') // 指向 根目录<br /><br />module.exports = {<br />entry: path.join(root, 'src/main.js'),  // 项目入口文件<br />output: {<br />path: path.join(root, 'dist'),  // 出口目录<br />filename: 'main.js'  // 出口文件名<br />    }<br />}<br /><br />以上便实现了“webpack src/main.js dist/main.js”webpack指定 入口文件 -> 出口文件 的功能了。<br /><br />此外还可以拓展一下,使得兼容更多的功能~ (webpack@2 resolving)<br /><br />const path = require('path')<br />const root = path.resolve(__dirname, '..') // 根目录<br /><br />module.exports = {<br />entry: path.join(root, 'src/main.js'),  // 入口文件<br />output: {<br />path: path.join(root, 'dist'),  // 出口目录<br />filename: 'main.js'  // 出口文件名<br />},<br />resolve: {<br />   alias: { // 配置目录别名,来确保模块引入变得更简单<br />     // 在任意目录下require('components/example') 相当于require('项目根目录/src/components/example')<br />     components: path.join(root, 'src/components'),<br />     views: path.join(root, 'src/views'),<br />     styles: path.join(root, 'src/styles'),<br />     store: path.join(root, 'src/store')<br />   },<br />   extensions: ['.js', '.vue'], // 引用js和vue文件可以省略后缀名 (此处有坑坑坑==。)!!webpack@2+已经不再要求强制转入一个空字符串<br />   resolveLoader: {<br />   module: { // 配置loader<br />   loaders: [<br />     {test: /.vue$/, loader: 'vue'}, // 所有.vue结尾的文件,使用vue-loader<br />     {test: /.js$/, loader: 'babel', exclude: /node_modules/} // .js文件使用babel-loader,切记排除node_modules目录<br />    ]<br />  }<br />}<br /><br />根目录下添加.babelrc用于配置 babel :<br /><br /> {<br /> "presets": ["es2015"]<br /> }  <br /><br />关于 Babel 是什么 : 通常与webpack搭配一起使用,webpack可以看作是是打包工具,babel则视为编译工具,可把最新标准编写的js代码(例如 es6,react..)编译成当下随处可用的版本。是一种“源码到源码”的编译(转换编译)!<br /><br /><br />而.babelrc就是让 Babel 做你要它做的事情的配置文件。<br /><br />babel-preset-es2015          打包了es6的特性<br /><br />使用了vue-loader和babel-loader需要安装包: 运行如下命令(可能有坑哦,若踩可见文末 bug修复篇==。)<br /><br />npm install --save-dev vue-loader@8 babel-loader babel-core babel-plugin-transform-runtime babel-preset-es2015 css-loader vue-style-loader vue-hot-reload-api@1 vue-html-loader<br /><br />3.在 webpack.json 中创建 dev.js<br /><br />   <br />  const path = require('path')<br />  const webpack = require('webpack')<br />  const merge = require('webpack-merge')<br />  const baseConfig = require('./base')<br />  const root = path.resolve(__dirname, '..')<br />      <br />  module.exports = merge(baseConfig, {})  首先 与base.js同样的配置  <br />  <br /><br />其中 webpack-merge 用于合并两个配置文件,需要安装 => npm install --save-dev webpack-merge<br /><br />4.自行搭建一个小型服务器,以免手动调试 index.html 。定义使用 webpack dev server 。 (webpack@2 Proxy) <br />因此需要继续配置dev.js如下: 还有其他一切配置,可查阅 webpack-dev-server-cli<br /><br />module.exports = merge(baseConfig, {<br />devServer: {<br />historyApiFallback: true, // 404的页面会自动跳转到/页面<br /> inline: true, // 文件改变自动刷新页面<br />// progress: true, // 显示编译进度 !!有坑,待解决。下同~ 暂时不加这两个属性继续走下去吧~!<br />// colors: true, // 使用颜色输出<br /> port: 3800, // 服务器端口  !!注意不要被占用了哦<br />},<br /> devtool: 'source-map' // 用于标记编译后的文件与编译前的文件对应位置,便于调试<br />})<br /><br />5.添加热替换配置 HotModuleReplacementPlugin ,每次改动文件不会再整个页面都刷新。该配置是webpack内部插件,不需要安装。<br /><br />module.exports = merge(baseConfig, {<br /> entry: [<br />   'webpack/hot/dev-server', // 热替换处理入口文件<br />    path.join(root, 'src/index.js')<br /> ],<br />devServer: { /* 同上 */},<br />plugins: [<br />new webpack.HotModuleReplacementPlugin() // 添加热替换插件<br />  ]<br />}  <br /><br />6.使用 HtmlWebpackPlugin ,实现js入口文件自动注入。npm install --save-dev html-webpack-plugin,且需要在头部引入 =>const HtmlWebpackPlugin = require('html-webpack-plugin') (还在dev.js中哦)<br /><br />module.exports = merge(baseConfig, {<br />entry: [ /* 同上 */ ],<br />devServer: { /* 同上 */ },<br />plugins: [<br />  new webpack.HotModuleReplacementPlugin(),<br />  new HtmlWebpackPlugin({<br />    template: path.join(root, 'index.html'), // 模板文件<br />    inject: 'body' // js的script注入到body底部<br />    })<br />  ]<br />}<br /><br />7.修改index.html(根目录i 啊),去掉入口文件的引入:<script src="dist/main.js"></script> <br />8.修改package.json 的运行脚本:<br /><br />{<br /> "dev": "webpack-dev-server --config webpack.config/dev.js"//指向配置文件,而不是某一单一页面的js<br />}  <br /><br />再来跑一下,检测是否webpack配置都成功运作了。创建一个vue组件 src/components/Hello.vue<br /><br /><template><br /><div>{{message}}</div><br /></template><br /><br /><script><br />  export default {<br />    data: () => ({message: 'Hello Vue.js!'})<br />   }<br /></script><br /><br />相应的main.js也做出修改:<br /><br />// import...from的语法是ES6的,由于已经安装了babel(可编译),故可以直接使用<br />import Vue  from 'vue'  <br />import Hello from './components/Hello.vue'<br /><br />new Vue({<br />  el: '#app',<br />  template: '<div><hello></hello></div>', <br />  components: {Hello}<br />})<br /><br />运行npm run dev,浏览器打开 localhost:3800 查看结果 Hello Vue.js! 并且改动页面会自动刷新,不需要再一遍遍command+r刷新啦。<br />step4   配置路由<br /><br />1.安装 vue-router: npm install --save vue-router@0.7 (当然了当下的vue + axois 会更搭哦)<br /><br />2.src下创建views文件夹,用于存放页面组件;另外再创建router文件夹,用于存放所有路由相关的配置<br /><br /><br />3.添加路由页面 src/views/Home.vue:<br /><br /><template><br />  <div><hello></hello></div><br /></template><br /><br /><script><br />  import Hello from 'components/Hello' //引入已写vue组件<br />  export default {<br />    components: {Hello}<br />   }<br /></script><br /><br />4.添加 src/router/routes.js 文件,用于配置项目路由:<br /><br />import Home from 'views/Home'<br /><br />export default {<br />  '/': {<br />    name: 'home',<br />    component: Home<br />     }<br /> }   <br /><br />5.添加路由入口文件 src/router/index.js:<br /><br />import Vue from 'vue'<br />import Router from 'vue-router'<br />import routes from './routes'<br /><br />Vue.use(Router)<br /><br />const router = new Router({<br />  hashbang: false,  // 关闭hash模式<br />  history: true,    // 开启html5history模式<br />  linkActiveClass: 'active' // v-link激活时添加的class,默认是`v-link-active`<br />})<br /><br />router.map(routes)<br /><br />router.beforeEach(({to, next}) => {<br />  console.log('---------> ' + to.name)  // 每次调整路由时打印,便于调试<br />  next()<br />})<br /><br />export default router  <br /><br />6.再次修改main.js:<br /><br />import Vue  from 'vue'<br />import router from './router'  //直接导入路由配置    <br /><br />const App = Vue.extend({})<br /><br />router.start(App, '#app')       <br /><br />7.最后别忘了index.html:<br /><br />     <div id="app">{{message}}</div>  <!-- 读取Vue,替换成  -->   <br />     <br />      <router-view></router-view><!--路由替换位置-->    <br /><br />可以再次执行 npm run dev: 浏览器直接访问 localhost:3800查看效果。<br />step5    配置Vuex<br /><br />(vuex)<br />专门为vue.js开发而配套的 状态管理模式 .通常用于存放和管理不同组件中的共用状态,例如不同路由页面之间的公共数据.<br /><br />其他 几个概念:<br />state:状态,即数据 ;<br />store:数据的集合,一个vuex引用,仅有一个store,包含n个state<br />mutation:state不能直接赋值,通过mutation定义最基本的操作<br />action:在action中调用一个或多个mutation<br />getter:state不能直接取值,使用getter返回需要的state<br />module:store和state之间的一层,便于大型项目管理,store包含多个module,module包含state、mutation和action<br />  <br />1.安装 : npm install --save vuex@1 添加 src/store 文件夹,存放vuex相关文件,添加 src/store/modules 用于vuex分模块管理 ;<br />2.添加 src/store/types.js,vuex的所有mutation type(操作类型)建议放在一起,有效避免重名情况:<br /><br />export const INCREASE = 'INCREASE' // 累加<br />export const RESET = 'RESET' // 清零  <br /><br />3.vuex模块,添加 counter 模块目录 store/modules/counter添加 store/modules/counter/actions.js:<br /><br />import {INCREASE, RESET} from 'store/types'<br /><br /> export const increase = (({dispatch}) => {<br /> dispatch(INCREASE) // 调用type为INCREASE的mutation<br />})<br /><br />export const reset = (({dispatch}) => {<br /> dispatch(RESET) // 调用type为RESET的mutation<br />})  <br /><br />添加 store/modules/counter/index.js<br /><br /> import{INCREASE, RESET} from 'store/types.js'<br /><br /> const state = {<br />    count: 0<br />  }<br /><br /> const mutations = {<br />  [INCREASE] (state) { state.count++ },<br />  [RESET] (state) { state.count = 0 }<br />}<br /><br />export default {state, mutations}  <br /><br />4.vuex入口文件: store/index.js:<br /><br />import Vue from 'vue'<br />import Vuex from 'vuex'<br />import counter  from 'store/modules/counter'<br /><br />Vue.use(Vuex) // 确保在new Vuex.Store()之前<br /><br />export default new Vuex.Store({<br />  modules: {counter}<br /> })  <br /><br />5.修改main.js,将store引入并添加到App中:<br /><br />import Vue  from 'vue'<br />import router from './router'<br />import store from 'store'<br /><br /><br />const App = Vue.extend({store})<br /><br />router.start(App, '#app')  <br /><br />6.改造一下 src/components/Hello.vue,把action用上:<br /><br /><template><br /> <div><br />    <p>{{message}}</p><br />    <p>click count: {{count}}</p><br />    <button @click="increase">increase</button><!--可以直接调用引入的action--><br />    <button @click="reset">reset</button><br />  </div><br /></template><br /><br /><script><br />  import {increase, reset} from 'store/modules/counter/actions' // 引入action<br />  export default {<br />    data: () => ({message: 'Hello Vue.js!'}),<br />    vuex: {<br />    actions: {increase, reset},<br />    getters: {<br />        count: ({counter}) => counter.count<br />      }<br />    }<br />  }<br /></script><br /><br />step6   配置eslint ---规范js编码<br /><br />eslint定义的是编码风格,巧妙利用提供的rules,可以自定义配置 ,增减规则 ; 同时,在使用中检测不通过,不一定不能运行,只是违反了规则==。监督自我。<br /><br />网上也已经有很多现有的配置了,建议(standard)<br />1.配置.eslintrc文件<br /><br />{<br />  "parser": "babel-eslint", // 支持babel<br />  "extends": "standard", // 使用eslint-config-standard的配置<br />  "plugins": [<br />     "html" // 支持.vue文件的检测<br />  ],<br />  "env": {<br />    "browser": true, // 不会将window上的全局变量判断为未定义的变量<br />    "es6": true // 支持es6的语法<br />  },<br />  "rules": { // 自定义个别规则写在这,0忽略,1警告,2报错<br />  "no-unused-vars": 1 // 将”未使用的变量“调整为警告级别,原为错误级别,更多规则请看官网<br />  }<br />}     <br /><br />用了啥就安装啥:npm install --save-dev eslint babel-esli nt eslint-config-standard eslint-plugin-standard eslint-plugin-html eslint-plugin-promis<br />step7 webpack生产环境配置 ---对于编译出来的文件进行压缩,提取公共模块等操作<br /><br />1.添加webpack.config/pro.js文件,相比dev.js把生产环境用不到的删掉,比如webpack-dev-server、webpack-hot-replacement.<br /><br /> const path = require('path')<br /> const webpack = require('webpack')<br /> const merge = require('webpack-merge')<br /> const HtmlWebpackPlugin = require('html-webpack-plugin')<br /> const baseConfig = require('./base')<br /> const root = path.resolve(__dirname, '..')<br /><br /> module.exports = merge(baseConfig, {<br />       plugins: [<br />        new HtmlWebpackPlugin({<br />        template: path.join(root, 'index.html'), // 模板文件<br />        inject: 'body' // js的script注入到body底部<br />     })<br />   ]<br />})<br /><br />(常用插件) :<br /><br />extract-text-webpack-plugin 提取css到单独的文件<br />compression-webpack-plugin 压缩gzip<br />webpack.optimize.UglifyJsPlugin 压缩js文件,内置插件<br />.....<br /><br />2.在package.json中添加运行脚本:"build": "webpack --config webpack.config/pro.js";<br /><br />3.运行npm run build,可以在dist文件夹中看到打包好的文件~~<br />webpack+vue的环境搭建到此算是初见雏形了,具体时实际运用还需要更多的实践常见错误总结安装一些npm包失败: 出现背景:执行npm install --save dev ....时<br /><br /><br />查问题shasum check failed:<br /><br /><br />人话:npm镜像源错误。<br /><br />解决:1.通过config命令<br /><br />npm config set registry http://registry.cnpmjs.org<br />npm info underscore  <br /><br />2.命令行指定<br /><br />npm --registry http://registry.cnpmjs.org info underscore<br /><br />以上两种都可以快速解决安装问题,但治标不治本,下次安装时仍会出现。因此推荐,直接在配置中指定写死,一劳永逸~<br /><br />3.编辑 ~/.npmrc 加入如下配置:<br /><br />registry = http://registry.cnpmjs.org<br /><br />npm版本太低报错:<br /><br /><br />解决:<br />1、首先安装n模块 npm install -g n<br /><br />2、升级node.js到最新稳定版 n stable<br />若确定在最新版本中还是在报错的话,则需要检查是否时webpack.config中配置有错误,webpack@1.xx->webpack@2.xx 各中的(升级特性) 还是很重要的<br />出现segmentation fault 11报错: 出现背景:在一次需要最新版本的node时,舍弃了$n stable稳定版(因为系统还是提示需要升级最新版)执行 sudo n latest 后升级过慢,中间不够稳定,直接强行被退出。之后再运行,关于npm 和node 的所有命令均在报segmentation fault 11这个错误。<br /><br /><br />以为os被玩坏了,系统错乱,吓死宝宝了==。<br /><br />原因:执行n命令,显示当前没有选中任何版本。 解决:用n命令重新设置要使用的版本 sudo n 版本号<br /><br />版本太低的报错<br /><br /><br />解决:执行npm install --save-dev eslint-plugin-import@^2.0.0<br />npm install --save-dev eslint-plugin-node@4.2.2<br />

正文结束

阿里云、腾讯云 apache的vhost配置https http协商缓存VS强缓存