webpack4搭建Vue开发环境笔记~~持续更新

2018-11-10 admin

项目git地址

一、node知识

__dirname: 获取当前文件所在路径,等同于path.dirname(__filename)

console.log(__dirname);
// Prints: /Users/mjr
console.log(path.dirname(__filename));
// Prints: /Users/mjr

path.resolve([…paths]): 把一个路径或路径片段的序列解析为一个绝对路径

  • 给定的路径的序列是从右往左被处理的,后面每个 path 被依次解析,直到构造完成一个绝对路径
  • 如果处理完全部给定的 path 片段后还未生成一个绝对路径,则当前工作目录会被用上
  • 生成的路径是规范化后的,且末尾的斜杠会被删除,除非路径被解析为根目录
  • 长度为零的 path 片段会被忽略
  • 如果没有传入 path 片段,则 path.resolve() 会返回当前工作目录的绝对路径
path.resolve('/foo/bar', './baz');
// 返回: '/foo/bar/baz'

path.resolve('/foo/bar', '/tmp/file/');
// 返回: '/tmp/file'

path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
// 如果当前工作目录为 /home/myself/node,
// 则返回 '/home/myself/node/wwwroot/static_files/gif/image.gif'

二、配置最基本的webpack

项目目录生成如下文件

.
├── build
│   ├── build.js
│   ├── index.html
│   ├── webpack.base.conf.js
│   ├── webpack.dev.conf.js
│   └── webpack.prod.conf.js
├── package.json
├── package-lock.json
└── src
    ├── App.vue
    ├── main.js
    ├── timg.gif
    └── timg.jfif

首先,先装下webpack依赖:

npm i webpack webpack webpack-cli -D

1、webpack.base.conf.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
  entry: {
    bundle: path.resolve(__dirname, '../src/main.js')
  },
  output: {
    path: path.resolve(__dirname, '../dist'),
    filename: '[name].[hash].js',
    publicPath: '/'
  },
  module: {
    rules: [

    ]
  },
  plugins: [
    <!-- 以当前目录的index.html为模板生成新的index.html,这个插件就是将新生成的文件(js,css)引入 -->
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, 'index.html')
    })
  ],
  resolve: {

  }
};

上面用到了html-webpack-plugin插件,装下:

npm i html-webpack-plugin -D

2、webpack.dev.conf.js

const merge = require('webpack-merge');
const path = require('path');
const baseConfig = require('./webpack.base.conf');
module.exports = merge(baseConfig, {
  // mode关系到代码压缩质量  https://webpack.docschina.org/guides/tree-shaking/
  mode: 'development',
  // source-map,将编译后的代码映射到原代码,便于报错后定位错误
  devtool: 'inline-source-map',
  <!-- webpack-dev-server配置项 -->
  devServer: {
    <!-- devserver启动服务的根路径 -->
    contentBase: path.resolve(__dirname, '../dist'),
    <!-- 打开浏览器 -->
    open: true
  }
});

合并webpack配置的插件webpack-merge,能够启一个简易服务的webpack-dev-server,详情

npm i webpack-dev-server webpack-merge -D

3、webpack.prod.conf.js

const merge = require('webpack-merge');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const path = require('path');
const baseConfig = require('./webpack.base.conf');
module.exports = merge(baseConfig, {
  mode: 'production',
  devtool: 'source-map',
  module: {
    rules: []
  },
  plugins: [
    new CleanWebpackPlugin(['dist/'], {
      root: path.resolve(__dirname, '../')
    })
  ]
});

清除文件的插件:

npm i clean-webpack-plugin -D

4、build.js

const webpack = require('webpack');
const config = require('./webpack.prod.conf');

webpack(config, (err, stats) => {
  if (err || stats.hasErrors()) {
    // 在这里处理错误
    console.error(err);
    return;
  }
  // 处理完成
  console.log(stats.toString({
    chunks: false,  // 使构建过程更静默无输出
    colors: true    // 在控制台展示颜色
  }));
});
// package.json
{
  +++
  "scripts": {
    "build": "node build/build.js",
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js"
  },
}

以上算是一个webpack的基本结构,如果入口文件(main.js)里引入的是正经js,npm dev和npm build是可以的打包编译的,但是我们是要写vue,那就要加些loader和plugins了

三、引入一些基本的loader

1、babel-loader

依赖安装要求:webpack 4.x | babel-loader 7.x | babel 6.x,注意babel-loader和babel的版本,不然会报错

npm install -D babel-loader@7 babel-core babel-preset-env webpack

然后再配置中加入

// base.conf.js
module.exports = {
  +++
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
        }
      },
      +++
    ]
  }
}

我们还需要添加一个配置文件(.babelrc)在根目录下:

/// .babelrc
{
  "presets": [
    ["env", {
      "targets": {
        "browsers": [">0.25%", "last 2 versions", "not ie 11", "not op_mini all"]
      }
    }]
  ]
}

这就是 babel-preset-env 的作用,帮助我们配置 babel。我们只需要告诉它我们要兼容的情况(目标运行环境),它就会自动把代码转换为兼容对应环境的代码。 以上代码表示我们要求代码兼容最新两个版本的浏览器,不用兼容 11(及以下)和Opera Mini,另外市场份额超过 0.25% 的浏览器也必须支持。 只需要告诉 babel-preset-env 你想要兼容的环境,它就会自动转换

2、url-loader、file-loader

如果我们希望在页面引入图片(包括img的src和background的url)。当我们基于webpack进行开发时,引入图片会遇到一些问题

其中一个就是引用路径的问题。拿background样式用url引入背景图来说,我们都知道,webpack最终会将各个模块打包成一个文件,因此我们样式中的url路径是相对入口html页面的,而不是相对于原始css文件所在的路径的。这就会导致图片引入失败。这个问题是用file-loader解决的,file-loader可以解析项目中的url引入(不仅限于css),根据我们的配置,将图片拷贝到相应的路径,再根据我们的配置,修改打包后文件引用路径,使之指向正确的文件

另外,如果图片较多,会发很多http请求,会降低页面性能。这个问题可以通过url-loader解决。url-loader会将引入的图片编码,生成dataURl。相当于把图片数据翻译成一串字符。再把这串字符打包到文件中,最终只需要引入这个文件就能访问图片了。当然,如果图片较大,编码会消耗性能。因此url-loader提供了一个limit参数,小于limit字节的文件会被转为DataURl,大于limit的还会使用file-loader进行copy。

url-loader和file-loader是什么关系呢?简答地说,url-loader封装了file-loader。url-loader赖于file-loader,即使用url-loader时,也要安装file-loader

npm i url-loader file-loader -D
/// base.conf.js
module.exports = {
  +++
  module: {
    rules: [
      +++
      {
        test: /\.(png|jpg|jfif|jpeg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              // 低于这个limit就直接转成base64插入到style里,不然以name的方式命名存放
              // 这里的单位时bit
              limit: 8192,
              name: 'static/images/[hash:8].[name].[ext]'
            }
          }
        ]
      },
      // 字体图标啥的,跟图片分处理方式一样
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        use: [
          {
            loader: 'url-loader',
            name: 'static/font/[hash:8].[name].[ext]'
          }
        ]
      },
    ]
  },
}

作用自己去看

npm i vue-loader -D
// base.conf.js
module.exports = {
  +++
  module: {
    rules: [
      +++
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ]
  }
}

在这里还要一个插件,这个插件是必须的!

// base.conf.js
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
  +++
  plugins: [
      // 它的职责是将你定义过的其它规则复制并应用到 .vue 文件里相应语言的块。
      // 例如,如果你有一条匹配 /\.js$/ 的规则,那么它会应用到 .vue 文件里的 <script> 块
      new VueLoaderPlugin(),
      +++
  ]
}

4、处理样式

  • less-loader: 将less转css
  • css-loader: 将css转为CommonJS规范的js字符串
  • style-loader: 将js字符串转为style node插入到html中
  • postcss-loader: PostCSS 是一个允许使用 JS 插件转换样式的工具,我们用postcss的插件就要配置它,autoprefixer就是postcss项目里的一个插件
  • autoprefixer: 添加了 vendor 浏览器前缀,它使用 Can I Use 上面的数据。
npm i less-loader css-loader style-loader less autoprefixer postcss-loader -D
const StyleLintPlugin = require('stylelint-webpack-plugin');
// base.conf.js
module.exports = {
  +++
  module: {
    rules: [
      {
        // less css
        test: /\.l?css$/,
        // use里的loader执行顺序为从下到上,loader的顺序要注意
        // 这里检测到less/css文件后需要将后续处理loader都写在此use里,如果less和css过分开检测处理,不能说先用less-loader转成css,然后让它走/\.css/里的use
        use: [
          {loader: 'style-loader'},
          {loader: 'css-loader'},
          {loader: 'postcss-loader'},
          {loader: 'less-loader'},
        ]
      },
      +++
    ]
  }
}

在根目录新建个postcss.config.js文件来配置autoprefixer,通过Browerslist来帮助你配置,浏览器市场份额,了解下browserl.ist

module.exports = {
  plugins: [
    require('autoprefixer')({
      "browsers": [
        "defaults",
        "not ie < 9",
        "last 2 versions",
        "> 1%",
        "iOS 7",
        "last 3 iOS versions"
      ]
    })
  ]
}
  • mini-css-extract-plugin提取css

这里打包cssless 为例,r如果要用mini-css-extract-plugin插件提取css,将上面改为如下:

npm install mini-css-extract-plugin -D
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
+++
module.exports = {
  +++
  // 模块,loader
  module: {
    rules: [
      +++
      {
        test: /\.l?(c|e)ss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {loader: 'css-loader'},
          {loader: 'postcss-loader'},
          {loader: 'less-loader'},
        ]
      },
      +++
    ]
  },
  // 插件
  plugins: [
    +++
    new MiniCssExtractPlugin({
      filename: 'static/css/[name].[hash].css',
      chunkFilename: 'static/css/[name].[hash].css'
    })
  ]
}

5、然后配置下别名resolve.extensions

// base.conf.js
module.exports = {
  +++
  resolve: {
    alias: {
      // 配置别名'vue/div>,不然import 'vue'时,webpack找不到
      'vue/div>: 'vue/dist/vue.esm.js',
      // 这个为src配置别名,非必需,为方便而已
      '@': path.resolve(__dirname, '../src')
    },
    // 在import这些拓展名的文件时,可以省略拓展名
    extensions: ['*', '.js', '.json', '.vue'],
  }
}

现在我们来测试以下,安装一个vue

npm i vue

在mian.js里面

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

new Vue({
  el: '#app',
  components: {App},
  template: '<App/>'
})

在App.vue里写入

<template>
  <div>
    <h3 class="title">{{title}}</h3>
    <p class="content">{{content}}</p>
    <div class="goddess">
      <div class="right">
        <h4 class="right__h4">background引入图片</h4>
        <div class="right__img"></div>
      </div>
      <div class="left">
        <h4 class="left__h4">img标签直接引入图片</h4>
        <img class="left__img" src="./timg.jfif" />
      </div>
    </div>
  </div>
</template>

<script>
export default {
  components: {
    Foot: Footer
  },
  data () {
    return {
      title: 'hello word',
      content: 'webpack4 搭建vue环境',
    }
  },
}
</script>

<style lang="less" scoped>
  .title {
    font-size: 20px;
    text-align: center;
    color: red;
  }
  .content {
    font-size: 14px;
    color: #333333;
  }
  .goddess {

    .left {
      margin-left: 50%;
      &__h4 {
        font-size: 14px;
      }
      &__img {
        width: 308px;
        height: 433px;
      }
    }
    .right {
      float: left;
      &__h4 {
        font-size: 14px;
      }
      &__img {
        width: 300px;
        height: 150px;
        background: url('./timg.gif') no-repeat;
      }
    }
  }
</style>

好了,npm dev 先看一下女神,放松一下:

图片描述

四、做一些优化

1、提取公共代码

使用 splitChucksPlugin 插件,这是 Webpack 自带的,不用安装第三方依赖,默认配置即可

<!-- base.conf.js -->
module.exports = {
  +++
  plugins: [
    +++
    new webpack.optimize.SplitChunksPlugin()
  ]
}

想了解这个插件的默认配置及如何配置,英文中文

2、将第三方库单独打包

每次我们对项目进行打包时,我们都会把引用的第三方依赖给打包一遍,比如 Vue、Vue-Router、React 等等。但是这些库的代码基本都是不会变动的,我们没必要每次打包都构建一次,所以我们最好将这些第三方库提取出来单独打包,这样有利于减少打包时间。 官方插件是 DllPlugin。推荐一个比较好用的插件 —— autodll-webpack-plugin

npm i autodll-webpack-plugin -D
// base.conf.js
module.exports = {
  +++
  plugins: [
   // 将一些不太可能改动的第三方库单独打包,会通过缓存极大提升打包速度
    new AutoDllPlugin({
      // will inject the DLL bundle to index.html
      // default false
      inject: true,
      debug: false,
      filename: '[name]_[hash].js',
      path: 'static',
      entry: {
        // [name] = vue, 在这里会将entry里的每个item(vue,jquery)都打包成一个js
        vue: [
          'vue',
          'vue-router'
        ],
        // [name] = jquery
        // jquery: [
        //   'jquery',
        //   'jquery-from'
        // ]
      }
    }),
    +++
  ]
}

inject 为 true,插件会自动把打包出来的第三方库文件插入到 HTML。filename 是打包后文件的名称。path 是打包后的路径。entry 是入口,vendor 是你指定的名称,数组内容就是要打包的第三方库的名称,不要写全路径,Webpack 会自动去 node_modules 中找到的。 每次打包,这个插件都会检查注册在 entry 中的第三方库是否发生了变化,如果没有变化,插件就会使用缓存中的打包文件,减少了打包的时间,这时 Hash 也不会变化。

3、热重载

“热重载”不只是当你修改文件的时候简单重新加载页面。启用热重载后,当你修改 .vue 文件时,该组件的所有实例将在不刷新页面的情况下被替换。它甚至保持了应用程序和被替换组件的当前状态!当你调整模版或者修改样式时,这极大地提高了开发体验,以下两种方式择一即可

"scripts": {
  +++
  "dev": "webpack-dev-server --hot --inline --progress --config build/webpack.dev.conf.js"
},
  • 方式2:或者通过配置webpack.dev.config.js,相比第一种,就会麻烦一点
const webpack = require('webpack')
module.exports = {
  +++
  module: {
    devServer: {
      +++
      // 开启热重载
      hot: true
    },
    plugins: [
      // 启用模块热替换(HMR)
      new webpack.HotModuleReplacementPlugin(),
      // 当开启 HMR 的时候使用该插件会显示模块的相对路径,建议用于开发环境。
      new webpack.NamedModulesPlugin(),
      +++
    ]
  }
}

4、eslint

对你有帮助的话点个刷波6,点个赞吧

原文链接:https://segmentfault.com/a/1190000016972438

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-45085.html

文章标题:webpack4搭建Vue开发环境笔记~~持续更新

相关文章
HTML5游戏2015年的开发趋势
在互联网行业中,一个行业从零到成熟,开发者生态也是对应的,我们今年看到很多大公司,包括像微软和Google,也参与到了HTML5 开发者生态的建设当中。关于HTML5移动游戏的开发和盈利生态的走向又该去往何处?下面我们来试着讨论一下。 《围...
2015-11-12
vue.js实现请求数据的方法示例
vue2.0示例代码如下: var vm = new Vue({ el:&quot;#list&quot;, data:{ gridData: &quot;&quot;, }, ...
2017-03-20
Html5 是否适合移动应用开发
HTML5最近这几年声誉鹊起,而基于HTML5技术的产品也风生水起。感觉现在你的产品要是不和HTML5沾点边,都不好意思和客户打招呼!移动应用开发中,HTML5更是不可或缺的角色,市面上不少移动应用中间件产品都号称支持HTML5,例如APP...
2015-11-12
最细致的vue.js基础语法 值得收藏!
介绍 前段时间接触到一个库叫做Vue.js, 个人感觉很棒,所以整理了一篇博文做个介绍。 Vue读音/vju:/,和view类似。是一个数据驱动的web界面库。Vue.js只聚焦于视图层,可以很容易的和其他库整合。代码压缩后只有24kb。 ...
2017-03-21
vuejs通过filterBy、orderBy实现搜索筛选、降序排序数据
直接贴代码了: 先上输入前的样子: &lt;style&gt; #example{margin:100px auto;width:600px;} .show{margin:10px;} #searchText{display: block...
2017-03-17
关于Ajax应用开发需要注意的事项
接触Ajax,那时候的Ajax支持还不是很好,都要涉及底层,没有现成的框架给你调用。现在把常见的问题列举如下。 [b]1、编码问题[/b] 注意AJAX要取的文件是UTF-8编码的。GB2312编码传回BROWSE后中文会乱码。如果用VBS...
2015-11-11
HTML5移动应用开发的12大特性
1.离线缓存为HTML5开发移动应用提供了基础 HTML5 Web Storage API可以看做是加强版的cookie,不受数据大小限制,有更好的弹性以及架构,可以将数据写入到本机的ROM中,还可以在关闭浏览器后再次打开时恢复数据,以减少...
2015-11-11
2015年2月国内操作系统市场份额概况,xp占46.29%,
规则调整:2012年6月1日开始,Mac操作系统中不再包含ipad、iphone市场份额。 ...
2015-11-12
2014年,你是不是被这5个HTML5技术刷屏了?
如今,几乎每天都有HTML5页面的推广以及小游戏、小测试在微信上传播,用户也逐渐习惯被各种HTML5轰炸。那么在刚刚过去的一年究竟有哪些HTML5技术堪称火爆,让人们的微信频频被刷屏呢? 1、2048 2048 在4x4的棋盘上,用方向键选...
2015-11-12
三步搞定vue在vscode的环境配置问题
1. vscode基础开发插件 vscode-icons 图标美化 Debugger for Chrome 调试 Beautify 代码格式化 Prettier 代码格式化 ESLint 代码规范 JavaScript (ES6) cod...
2017-12-25
回到顶部