webpack4.0从零搭建一个vue项目

开始之前先了解一下webpack的几个核心概念。

  • entry: 入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。
  • output: output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。
  • loader: loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)
  • plugins: loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务
  • 模式(mode): 通过选择 development 或 production 之中的一个,来设置 mode 参数,你可以启用相应模式下的 webpack 内置的优化

开始撸代码:

1、新建一个文件夹取名myWebpack,进入文件夹执行下面的代码

npm init -y
npm i webpack webpack-cli webpack-dev-server --save-dev

注意:
这里的–save-dev意思是安装在开发环境下,如果没有-dev则是安装在生产环境下,生产环境的代码是打包成静态文件的,所以只需要安装在开发环境就行

2、修改代码 package.json 中 scripts 部分:

"scripts": {
  "build": "webpack"
}

这时myWebpack下的package.json如下:

{
  "name": "myWebpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
     "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.14.0",
    "webpack-cli": "^3.0.8",
    "webpack-dev-server": "^3.11.0"
  }
}

此时,我们执行 npm run build, 会给出以下提示/错误:
webpack4.0从零搭建一个vue项目_第1张图片

1、error: 没有入口文件
2、warning: 建议设置 mode 选项

3、我们来做一些配置解决上面的两个问题
在文件根目录下新建webpack.config.js(名字可以随便取),内容如下:

const path = require('path');

module.exports = (env, argv) => {
    return {
        mode: 'production' // production | development
    }
}

再次运行npm run build就打包成功了,但是这个时候是webpack默认的一些配置,部分浏览器还不能解析es6的语法,所以我们下面来搞点事情。

接下来要做的事:

1、转换 ES6 代码,解决浏览器兼容问题(js)
2、编译css,自动添加前缀,抽取css到独立文件
3、复制并压缩html文件 html-webpack-plugin
4、打包前清理源目录文件(dist) clean-webpack-plugin
5、静态资源处理 file-loader(图片、视频等)
6、development 模式下启动服务器并实时刷新 webpack-dev-server
7、使用 webpack 4 建立 vue 项目

用 babel 转换 ES6 代码

npm i babel-core babel-loader babel-preset-env --save-dev

在根目录新建一个babel配置文件 .babelrc:

    {
        "presets": [
            "env"
        ]
    }

1、webpack.config.js

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

2、 npm scripts 中配置的方法:

"scripts": {
    "start": "webpack-dev-server --mode development --open",
    "build": "webpack --config=webpack.config.js --module-bind js=babel-loader --mode production"
  },

使用 babel-polyfill 解决兼容性问题

我们用 babel-polyfill 解决浏览器依然不支持的一些语法,导致的兼容性问题。

npm i babel-polyfill babel-plugin-transform-runtime --save-dev

.babelrc 添加配置:

{
    "presets": [
        "env"
    ],
    "plugins": [
       "transform-runtime"
    ]
}

最后在 webpack.config.js 中将 babel-polyfill 加到你的 entry 数组中:

const path = require('path');
module.exports = {
    entry: [
        "babel-polyfill", // 解决浏览器对js语法的兼容性
        path.join(__dirname, './src/index.js')  // 入口文件
    ],
};

编译css,自动添加前缀,抽取css到独立文件

webpack 并不会主动将你的css代码提取到一个文件,过去我们使用 extract-text-webpack-plugin,在webpack4中我们使用mini-css-extract-plugin来解决这个问题。

postcss-loader 用于添加浏览器前缀,相关配置我喜欢在根目录新建 postcss.config.js 配置

    npm i mini-css-extract-plugin css-loader style-loader postcss-loader sass-loader --save-dev

1、webpack.config.js

    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    module.exports = (env, argv) => {
      // 这里的mode只有当package.json的scripts中设置了mode时才有值
      const devMode = argv.mode !== 'production' 
      
      return {
        module: {
          rules: [
            // ...,
            {
                test: /\.(sa|sc|c)ss$/, // 压缩css文件
                use: [
                    devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
                    { loader: "css-loader" },
                    { loader: "postcss-loader" },
                    { loader: "sass-loader" }
                ]
            },
            ]
          },
          plugins: [
            // ...,
            new MiniCssExtractPlugin({  // 提取css为单独的文件,若无此项css将被打包进js文件
                filename: 'css/[name].[hash].css',
                chunkFilename: 'css/[name].[hash].css',
            }),
          ]
      }
    }

2、postcss.config.js

module.exports = {
    plugins: {
        autoprefixer: {}
    }
}

复制并压缩html文件 html-webpack-plugin

npm i html-webpack-plugin html-loader --save-dev

webpack.config.js

const HtmlWebPackPlugin = require("html-webpack-plugin");
    module.exports = {
        module: {
            rules: [
                // ...,
                {
                    test: /\.html$/, // 无此项将不能压缩html
                    use: [{
                        loader: "html-loader",
                        options: {
                            minimize: true
                        }
                    }]
                }
            ]
        },
        plugins: [
            new HtmlWebPackPlugin({ // html打包压缩插件,若无此项,html文件将不会压缩也不会进入打包目录
                template: "index.html",
                filename: "./index.html"
            }),
        ]
    };

打包前清理源目录文件 clean-webpack-plugin

每次打包,都会生成项目的静态资源,随着某些文件的增删,我们的 dist 目录下可能产生一些不再使用的静态资源,webpack并不会自动判断哪些是需要的资源,为了不让这些旧文件也部署到生产环境上占用空间,所以在 webpack 打包前最好能清理 dist 目录。

npm install clean-webpack-plugin --save-dev

下面是最新的写法,原来那种方式已经不行了,需要注意。

  const { CleanWebpackPlugin } = require('clean-webpack-plugin');
  module.exports = {
    plugins: [
      new CleanWebpackPlugin(), // 打包之前清理上一次打包的文件夹
    ]
  };

静态资源处理 file-loader

npm install file-loader --save-dev

webpack.config.js

module.exports = {
      module: {
        rules: [
          {
            test: /\.(png|jpg|jpeg|gif)$/, // 打包图片文件到指定目录
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            context: __dirname + '/',
                            name: devMode ? '[path][name].[ext]' : '[hash].[ext]',
                            // publicPath: devMode ? 'src/assets' : '../dist/img/', // 引入图片的图片路径,比如css引入的图片路径'../images/xx.jpg'将变为‘../img/xx.jpg’
                            outputPath: devMode ? '' : 'img/', // 打包后存放的目录
                            esModule: false // 此项为webpack4新特性,不设置则引入的图片路径均变为[object module]
                        }
                    }
                ]
            ]
          }
        ]
      }
    }

development 模式下配置服务器端口

plugins: [],
devServer:{
  // 设置基本目录结构
  contentBase:path.resolve(__dirname,'./'),
  //服务器的ip地址 可以使用ip也可以使用localhost
  host:'localhost',
  //服务器压缩是否开启
  compress:true,
  //配置服务端口号
  port:9999
}

使用 webpack 4 建立 vue 项目

修改目录结构如下

  ├── src
  │   ├── assets          # 静态资源
  │   │   └── logo.png
  │   ├── components      # 组件
  │   │   └── demo.vue
  │   └── styles
  │   │   └── index.css
  │   ├── index.js        # 入口文件
  │   ├── app.vue        # 最外层那个组件
  ├── .babelrc
  ├── index.html  # html模板
  ├── package-lock.json
  ├── package.json
  ├── postcss.config.js
  └── webpack.config.js
    npm i vue --save
    npm i vue-loader vue-template-compiler node-sass sass-loader --save-dev

1、webpack.config.js

	const VueLoaderPlugin = require('vue-loader/lib/plugin')
	
	module.exports = (env, argv) => {
        const devMode = argv.mode !== 'production'
        return {
	        resolve: {
	            extensions: ['.vue','.js','.css'], // 配置了这一项,引入的对应文件后缀自动解析,比如引入app.vue,只需要写app即可
	            alias: {
	                'vue$': 'vue/dist/vue.esm.js' //内部为正则表达式  vue结尾的
	            }
	        },
           entry: [
                "babel-polyfill", // 解决浏览器对js语法的兼容性
	            path.resolve(__dirname, './src/index.js') // 入口文件
	        ],
	        output: {
	            path: path.resolve(__dirname, 'dist'),
	            filename: "js/[name].[chunkhash].js" // js文件将打包到dist/js/name.hash.js
	        },
            module: {
                rules: [
                    // ...
                    // 解析vue
                    {
                        test: /\.vue$/,
                        loader: 'vue-loader',
                        options: {
                            loaders: {}
                        }
                    },
                    // 处理scss
                    {
                        test: /\.scss$/,
                        use: [
                            devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
                            'css-loader',
                            'postcss-loader',
                            'sass-loader',
                        ]
                    }
                ]
            },
            plugins: [
                // ...
                new VueLoaderPlugin()
            ]
        }
    };

2、index.js

import Vue from 'vue'
import app from './app'

new Vue({
    el: '#app',
    template: '',
    components: { app }
})

一个简单的vue项目就搭建好了。

下面npm run build走一个看看效果:
webpack4.0从零搭建一个vue项目_第2张图片
送上源码地址,供交流学习。

你可能感兴趣的:(webpack)