webpack4,vue开发环境,生产环境打包配置

一,node知识补充

__dirname:当前模块的目录名。 与 __filename 的 path.dirname() 相同。

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

path.resolve([…paths]):path.resolve() 方法将路径或路径片段的序列解析为绝对路径。

  1. 给定的路径序列从右到左进行处理,每个后续的 path 前置,直到构造出一个绝对路径。
  2. 如果在处理完所有给定的 path 片段之后还未生成绝对路径,则再加上当前工作目录。
  3. 生成的路径已规范化,并且除非将路径解析为根目录,否则将删除尾部斜杠。
  4. 零长度的 path 片段会被忽略。
  5. 如果没有传入 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'

二,基本配置(先搭建起一个能用的框架,后面再完善)

项目目录如下

.
|---config
|   |---webpack.base.conf.js
|   |---webpack.dev.conf.js
|   |---webpack.prod.conf.js
|---dist
|---src
|   |---components
|	|	|---app.vue
|	|---static
|	|	|---css
|	|	|---images
|	|	|---fonts
|	|---main.js
|---package.json		

新建一个文件夹,先初始化一下项目

$ npm init -y

安装webpack webpack-cli

$ npm i webpack webpack-cli   -D

1,webpack.base.conf.js(基础配置)

下面的代码要用到 html-webpack-plugin插件(自动将打包好的js,css引入到html中)

$ npm i html-webpack-plugin -D
/**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:8].js',
        publicPath: '/'
    },

    module: { // 对 高级js语法 和 非js文件 的处理
        rules: []
    },
    plugins: [ // 插件配置(工具,整合资源,压缩文件等)
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, '../index.html'),
            filename: "index.html", 
        })
    ],
}

2,webpack.dev.conf.js(开发环境配置)

下面的代码要用到webpack-merge插件(合并webpack配置)

$ npm i webpack-merge webpack-dev-server -D
/**webpack.dev.conf.js */
const merge = require('webpack-merge')
const path = require('path')
const BaseConfig = require('./webpack.base.conf.js')

module.exports = merge(BaseConfig, {
    // mode关系到代码压缩质量  https://webpack.docschina.org/guides/tree-shaking/
    mode: 'development',
    // source-map,将编译后的代码映射到原代码,便于报错后定位错误
    devtool: "inline-source-map",
    devServer: { //开发模式服务器配置
        contentBase: path.resolve(__dirname, '../dist'),
        open: true,
        overlay: true, // 编译出现错误时,将错误直接显示在页面上
        hot: true,
        port:8811,
        proxy: { // 代理地址
            "/api":"192.168.10.157:8811"
        }
    },
    plugins: []
})

3,webpack.prod.conf.js(生产环境配置)

下面的代码要用到clean-webpack-plugin插件(每次打包时先清除dist文件夹)

$ npm i webpack-merge -D
/**webpack.prod.conf.js */
const path = require('path')
const merge = require('webpack-merge')
const BaseConfig = require('./webpack.base.conf.js')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')

module.exports = merge(BaseConfig, {
    mode: 'production',
    // devtool:"source-map",  // 生成环境不配置devtool 就不用生成json了
    module: { //生产环境用到的特殊的loader 
        rules: []
    },
    plugins: [
        new CleanWebpackPlugin({})
    ]
})

4,package.json中增加脚本配置

/** package.json*/
+++
 "scripts": {
    "build": "webpack --config ./config/webpack.prod.conf.js",
    "dev": "webpack-dev-server --config ./config/webpack.dev.conf.js"
  },
+++

小结:

完成上面的基本配置 已经可以上手试一下了
在根目录下创建index.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>Documenttitle>
head>
<body>
    <div id="app">
    	点击一下弹窗
    div>
body>
html>

在/src文件夹下创建main.js

document.getElementById("app").onclick = function () { 
    alert("hello")
}

npm run build 或者 你npm run dev 试一下

三,引入一些基本的loader

1,babel-loader:用来处理高级js语法

安装babel-loader 及一些必要的插件

$ npm install -D babel-loader @babel/core @babel/preset-env webpack
/**webpack.base.conf.js */
module.exports = {
 module: { // 对 高级js语法 和 非js文件 的处理
        rules: [
        +++
        	{ // 高级 js语法处理
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader'
                }
            }
         +++
        ]
    },
}

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

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

这就是 babel-preset-env 的作用,帮助我们配置 babel。我们只需要告诉它我们要兼容的情况(目标运行环境),它就会自动把代码转换为兼容对应环境的代码。
以上代码表示我们要求代码兼容最新两个版本的浏览器,不用兼容 8(及以下)和 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 file-loader url-loader -D
module.exports = {
 module: { // 对 高级js语法 和 非js文件 的处理
        rules: [
       +++
        { //各种文件处理
                test: /\.(png|jpg|gif|jpeg|jfif)$/,
                use: [{
                    loader: 'url-loader',
                    options: {
                        // 低于这个limit就直接转成base64插入到style里,不然以name的方式命名存放
                        // 这里的单位时bit
                        limit: 8192,
                        name: 'static/images/[name].[hash:8].[ext]'
                    }
                }]
            },
            { // 字体文件处理
                test: /\.(woff|woff2|eot|ttf|otf|svg)$/,
                use: [{
                    loader: "url-loader",
                    options: {
                        name: 'static/font/[name].[hash:8].[ext]',
                        limit:5000, // 大于5K单独打包,小于5K直接以base64储存在css中
                        publicPath: "/",
                        outputPath: "/"
                    }
                }]
            },
       +++
        ]
    },
}

3,处理vue文件

需要安装vue-loader和 vue-template-compiler

$ npm install -D vue-loader vue-template-compiler
/**webpack.base.conf.js */
+++
const VueLoaderPlugin = require('vue-loader/lib/plugin')
+++

module.exports = {
 module: { // 对 高级js语法 和 非js文件 的处理
        rules: [
        +++
        	{ // 处理vue
                test: /\.vue$/,
                loader: 'vue-loader'
            },
         +++
        ]
    },
 plugins: [ // 插件配置(工具,整合资源,压缩文件等)
	 +++
	 new VueLoaderPlugin(),
	 +++
 ]
}

4,样式处理

  • sass-loader: 将 sass,scss 转为 css
  • css-loader: 将 css 转为 CommonJS 规范的 js 字符串
  • style-loader: 将 js 字符串转为 style node 插入到 html 中
  • postcss-loader: PostCSS 是一个允许使用 JS 插件转换样式的工具,我们用 postcss 的插件就要配置它,autoprefixer 就是 postcss 项目里的一个插件
  • autoprefixer: 为css样式适配不同的浏览器,添加前缀。

需要下载如下依赖

$ npm i -D style-loader css-loader sass sass-loader node-sass fibers postcss-loader autoprefixer
/**webpack.base.conf.js */

module.exports = {
 module: { // 对 高级js语法 和 非js文件 的处理
        rules: [
        +++
        	 { // 处理样式文件
                test: /\.(sass|scss)$/,
                use: [
                     {    
                         loader: "style-loader"  // 将处理结束的css代码存储在js中,运行时嵌入`