VUE template 从0到1

源码地址

初始化项目

mkdir vue-template && cd vue-template
npm init

安装 webpack

npm i -D webpack
npm i -D webpack-cli

ES6转ES5

npm i -D babel-loader @babel/core @babel/preset-env

在根目录创建 src文件夹,再创建main.js,并写入:

//  src/main.js
let a = 4;
console.log('hello webpack ' + a);

在根目录创建webpack.config.js,并写入:

module.exports = {
    mode: 'development',// 指定开发者打包模式
    entry : './src/main.js',//入口文件
    output : {//输出文件
        filename : 'index.js',//输出文件名
        path :  __dirname+'/public'//输出文件路径
    },
    module : {
        rules: [
            {/*将js或者jsx文件转码成es5*/
                test: /\.jsx?$/,// 正则惰性匹配后缀名为js或者jsx的文件
                exclude: /node_modules/,//排除这个文件夹
                use: {
                    loader: 'babel-loader',
                    options: {
                      presets: ['@babel/preset-env']
                    }
                  }
            },
        ]
    },
};

package.json中加入命令:

"build": "webpack --config ./webpack.config.js",

运行:
npm run build

根目录下会生成public文件夹,并且里面有一个由 src/main.js打包出来index.js

使用 html-webpack-plugin 创建 html 页面

安装 html-webpack-plugin 插件

npm install html-webpack-plugin -D

添加入口文件

在根目录下新增 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>hellow diyVue</title>
</head>
<body>
  <div id="app"></div>
<script type="text/javascript" src="index.js"></script></body>
</html>

修改 webpack.config.js 配置

const path = require('path');
const HtmlWebpackplugin = require('html-webpack-plugin');
module.exports = {
    mode: 'development',// 指定开发者打包模式
    entry : './src/main.js',//入口文件
    output : {//输出文件
        filename : 'index.js',//输出文件名
        path :  __dirname+'/public'//输出文件路径
    },
    module : {
        rules: [
            {/*将js或者jsx文件转码成es5*/
                test: /\.jsx?$/,// 正则惰性匹配后缀名为js或者jsx的文件
                exclude: /node_modules/,//排除这个文件夹
                use: {
                    loader: 'babel-loader',
                    options: {
                      presets: ['@babel/preset-env']
                    }
                  }
            },
        ]
    },
    plugins:[
        new HtmlWebpackplugin({
            filename: 'index.html', // 打包后的文件名,默认是index.html
            template: path.resolve(__dirname, 'index.html') // 导入被打包的文件模板
        })
    ]
}

查看效果

运行npm run build,可以看到public文件夹生成index.html,并且还引入了 src/main.js的压缩包index.js

安装并使用 vue

安装插件及vue

npm install vue-loader vue-template-compiler cache-loader thread-loader -D
npm install vue -S
  • vue-loader:用于解析.vue文件
  • vue-template-compiler:用于编译模板
  • cache-loader:用户缓存loader编译的结果
  • thread-loader:使用 worker 池来运行 loader,每个worker 都是一个nodejs 进程

修改webpack.config.js配置

const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackplugin = require('html-webpack-plugin');
module.exports = {
    mode: 'development',// 指定开发者打包模式
    entry : './src/main.js',//入口文件
    output : {//输出文件
        filename : 'index.js',//输出文件名
        path :  __dirname+'/public'//输出文件路径
    },
    module : {
        rules: [
            {/*将js或者jsx文件转码成es5*/
                test: /\.jsx?$/,// 正则惰性匹配后缀名为js或者jsx的文件
                exclude: /node_modules/,//排除这个文件夹
                use: {
                    loader: 'babel-loader',
                    options: {
                      presets: ['@babel/preset-env']
                    }
                  }
            },
            {
                test: /\.vue$/,
                use: [
                  {
                    loader: 'cache-loader'
                  },
                  {
                    loader: 'thread-loader'
                  },
                  {
                    loader: 'vue-loader',
                    options: {
                      compilerOptions: {
                        preserveWhitespace: false
                      },
                    }
                  }
                ]
              },
        ]
    },
    plugins:[
        new HtmlWebpackplugin({
            filename: 'index.html', // 打包后的文件名,默认是index.html
            template: path.resolve(__dirname, 'index.html') // 导入被打包的文件模板
        }),
        new VueLoaderPlugin()
    ]
}

使用vue

src下新建App.vue,并写入:

<template>
  <div class="App">
    Hello {{msg}}
  </div>
</template>

<script>
export default {
  name: 'App',

  data() {
    return {
        msg: "Vue",
    };
  }
};
</script>

修改 src/main.js代码:

import Vue from 'vue'
import App from './App.vue'

new Vue({
  render: h => h(App)
}).$mount('#app')

打包及运行vue

运行npm run build,在浏览器打开public/index.html,即可看到浏览器显示:hello vue

安装本地服务及代码热加载

安装 webpack-dev-server

npm i -D webpack-dev-server

修改webpack.config.js配置

// ...
mode: 'development',// 指定开发者打包模式
  devServer: { //node本地服务器
    host: '127.0.0.1',
    port: 8010
  },
  entry : './src/main.js',//入口文件
// ...

修改package.json

加入:

"dev": "webpack-dev-server --env.dev",

运行查看结果:

安装Vue-Router

装依赖

npm i -S vue-router

创建相关文件

page1.vue

<template>
    <div>
        page 1
    </div>
</template>

<script>
  export default {
    name: "page1"
  }
</script>

<style scoped>

</style>

page2.vue

<template>
    <div>
        page 2
    </div>
</template>

<script>
  export default {
    name: "page2"
  }
</script>

<style scoped>

</style>

src 下新增router/index.js文件:

import Vue from 'vue'
import VueRouter from "vue-router";
import page1 from '../page/page1.vue';
import page2 from '../page/page2.vue';

Vue.use(VueRouter);
export default new VueRouter({
  mode: 'hash',
  routes: [
    {
      path: '/page1',
      component: page1
    },
    {
      path: '/page2',
      component: page2
    },
    {
      path: '*',
      redirect: '/page2'
    }
  ]
});

修改 main.js

import Vue from 'vue'
import App from './App.vue';
import router from './router'

new Vue({
  router,
  render: h => h(App)
}).$mount('#app');

修改App.vue组件

<template>
    <div>
        <div class="App">
            Hello {{msg}}
        </div>

        <div>
            <router-link to="/page1">go page1</router-link>
            <router-link to="/page2">go page2</router-link>
        </div>
        <div>
            <router-view></router-view>
        </div>
    </div>
</template>

<script>
  export default {
    name: 'App',

    data() {
      return {
        msg: "Vue",
      };
    }
  };
</script>

运行npm run dev

配置基础组件

安装依赖

npm i -D sass-loader dart-sass css-loader style-loader file-loader url-loader postcss-loader autoprefixer
  • sass-loader,dart-sassscss/sass将语法转为css
  • css-loader:解析css文件
  • style-loader:将css解析到html页面的style
  • postcss-loader,autoprefixer:实现自动添加css3前缀

webpack.config.js中添加:

{
        test: /\.(scss|sass)$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader'
          },
          {
            loader: 'sass-loader',
            options: {
              implementation: require('dart-sass')
            }
          },
          {
            loader: 'postcss-loader',
            options: {
              plugins: [
                require("autoprefixer") /*自动添加前缀*/
              ]
            }
          }
        ]
      },
      {
        test: /\.(png|jpg|jpeg|gif|eot|ttf|woff|woff2|svg|svgz)(\?.+)?$/,
        use: [{
          loader: 'url-loader',
          options: {
            limit: 10000
          }
        }]
      }

运行及测试

src/App.vue中加入样式:

.app {
        color: red;
}

自定义环境变量及常量

创建常量文件config/constant.js,并写入:

const NODE_ENV = process.env.NODE_ENV; 
const config = {
  production: 'http://production',
  development: 'http://development',
};
module.exports = config[NODE_ENV];

修改webpack.config.js

const webpack = require('webpack');
const constant = require('./config/constant'); // 引入常量文件
// ...
plugins:[
        // ...
        new webpack.DefinePlugin({ // 定义全局变量
          CONSTANT: JSON.stringify(constant)
        })
    ],

修改package.json

"dev": "cross-env NODE_ENV=development webpack-dev-server",
"build": "cross-env NODE_ENV=production webpack --config ./webpack.config.js",

安装 cross-env

npm i -D cross-env

cross-env用于磨平mac 和win中的node环境之间的不同

运行

npm run dev

区分开发和生产打包

在config下创建dev和prod的webpack文件

  • 公共 webpack.config.js
const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackplugin = require('html-webpack-plugin');
const webpack = require('webpack');
const constant = require('./config/constant'); // 引入常量文件
module.exports = {
  entry: './src/main.js',//入口文件
  output: {//输出文件
    filename: 'index.js',//输出文件名
    path: __dirname + '/public',//输出文件路径
    // publicPath: "public", // 虚拟目录,自动指向path编译目录,放在内存中,所以在硬盘上是找不到的 默认是:/
  },
  module: { // 当执行require或import命令时匹配下面的加载规则
    rules: [
      {/*将js或者jsx文件转码成es5*/
        test: /\.jsx?$/,// 正则惰性匹配后缀名为js或者jsx的文件
        exclude: /node_modules/,//排除这个文件夹
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      },
      { // vue文件处理
        test: /\.vue$/,
        use: [
          {
            loader: 'cache-loader'
          },
          {
            loader: 'thread-loader'
          },
          {
            loader: 'vue-loader',
            options: {
              compilerOptions: {
                preserveWhitespace: false
              },
            }
          },
        ]
      },
      {
        test: /\.(png|jpg|gif|svg)/,
        use: [{
          loader: "file-loader",
          options: {
            name: '[name].[ext]',
            outputPath: "public/assets/", // 输出目录
            limit: 8192,
          }
        }]
      }
    ]
  },
  plugins: [
    new HtmlWebpackplugin({
      filename: 'index.html', // 打包后的文件名,默认是index.html
      template: path.resolve(__dirname, 'index.html') // 导入被打包的文件模板
    }),
    new VueLoaderPlugin(),
    new webpack.DefinePlugin({ // 定义全局变量
      CONSTANT: JSON.stringify(constant)
    })
  ],
};
  • 开发环境webpack.dev.js
    • 不需要压缩代码
    • 需要本地服务和热更新
    • css 不需要提取到 css文件
    • sourceMap
const merge = require('webpack-merge');
const webpackConfig = require('../webpack.config')
module.exports = merge(webpackConfig, {
  devtool: 'cheap-module-eval-source-map',
  mode: 'development',// 指定开发者打包模式
  devServer: { //node本地服务器
    host: '127.0.0.1',
    port: 8010
  },
  module: {
    rules: [
      {
        test: /\.(scss|sass)$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader'
          },
          {
            loader: 'sass-loader',
            options: {
              implementation: require('dart-sass')
            }
          },
          {
            loader: 'postcss-loader',
            options: {
              plugins: [
                require("autoprefixer") /*自动添加前缀*/
              ]
            }
          }
        ]
      },
    ]
  },
});
  • 生产环境webpack.prod.js
    • 压缩代码
    • 不需要本地服务和热更新
    • 提取 css,压缩css
    • sourceMap
    • 构建前清楚上一次构建的内容
const path = require('path')
const merge = require('webpack-merge')
const webpack = require('webpack')
const webpackConfig = require('../webpack.config')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssnanoPlugin = require('@intervolga/optimize-cssnano-plugin');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = merge(webpackConfig, {
  mode: 'production',// 指定开发者打包模式压缩js代码
  devtool: '#source-map',
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendors: {
          name: 'chunk-vendors',
          test: /[\\\/]node_modules[\\\/]/,
          priority: -10,
          chunks: 'initial'
        },
        common: {
          name: 'chunk-common',
          minChunks: 2,
          priority: -20,
          chunks: 'initial',
          reuseExistingChunk: true
        }
      }
    }
  },
  module: {
    rules: [
      {
        test: /\.(scss|sass)$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 2
            }
          },
          {
            loader: 'sass-loader',
            options: {
              implementation: require('dart-sass')
            }
          },
          {
            loader: 'postcss-loader',
            options: {
              plugins: [
                require("autoprefixer") /*自动添加前缀*/
              ]
            }
          }
        ]
      },
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/[name].[contenthash:8].css',
      chunkFilename: 'css/[name].[contenthash:8].css'
    }),
    new OptimizeCssnanoPlugin({
      sourceMap: true,
      cssnanoOptions: {
        preset: [
          'default',
          {
            mergeLonghand: false,
            cssDeclarationSorter: false
          }
        ]
      }
    }),
    new CopyWebpackPlugin([
      {
        from: path.resolve(__dirname, '../public'),
        to: path.resolve(__dirname, '../dist')
      }
    ]),
    new CleanWebpackPlugin(), // 用于删除上次构建的文件
  ]
});

安装依赖

npm i -D @intervolga/optimize-cssnano-plugin mini-css-extract-plugin clean-webpack-plugin webpack-merge copy-webpack-plugin
  • @intervolga/optimize-cssnano-plugin:用于压缩css代码
  • mini-css-extract-plugin:提取css到文件中
  • clean-webpack-plugin: 删除删词构建的文件
  • webpack-merge:合并webpack配置
  • copy-webpack-plugin:拷贝静态资源

修改package.json

"dev": "cross-env NODE_ENV=development webpack-dev-server --config ./config/webpack.dev.js",
"build": "cross-env NODE_ENV=production webpack --config ./config/webpack.prod.js",

运行

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

推荐阅读更多精彩内容