大前端【2-2练习】模块化开发

模块化开发作业

1、Webpack 的构建流程主要有哪些环节?如果可以请尽可能详尽的描述 Webpack 打包的整个过程。

项目中要有文件:webpack.config.js,它是运行在nodeJs中的一个文件,需要根据commonJs规范来编写代码,文件导出一个对象,我们根据导出的对象完成一系列配置。

构建流程

webpack启动的时候,会加载entry配置的入口文件,递归解析entry依赖的所有module,按照module.rules的规则进行匹配转化,对Module进行转换后,再解析出当前Module依赖的Module,这些Module会以Entry为单位进行分组,即为一个Chunk。因此一个Chunk,就是一个Entry及其所有依赖的Module合并的结果。最后Webpack会将所有的Chunk转换成文件输出Output。在整个构建流程中,Webpack会在恰当的时机执行Plugin里定义的逻辑,从而完成Plugin插件的优化任务。

2、Loader 和 Plugin 有哪些不同?请描述一下开发 Loader 和 Plugin 的思路。

loader

对模块进行加载、处理、编译转换,在module的rules中进行配置,如下:如果遇到后缀为css的文件,则会使用css-loader和style-loader进行编译转换。

loader更像是一个管道,将文件通过参数传递,然后经过一系列的处理,最终将文件输出。

 rules: [
           {
              test: /.css$/,
              use: [
                 'style-loader',
                 'css-loader'
                ]
            },
            {
               test: /.jpg$/,
               use: 'file-loader'
            },
     ]

plugin

相比于loader,Plugin拥有更宽的能力范围,loader只是在加载的环节工作,而插件触及到webpack工作的每一个环节。 Plugin用来扩展webpack功能,实现原理是在构建流程里注入钩子函数。在plugins数组中进行配置。例如:Webpack要求插件必须是一个函数或者是一个包含apply方法的对象。

 plugins: [
    new CleanWebpackPlugin()
  ]

3、使用 Webpack 实现 Vue 项目打包任务

依赖:

"devDependencies": {
    "@babel/core": "^7.10.5",
    "@babel/preset-env": "^7.10.4",
    "@vue/cli-plugin-babel": "^4.4.6",
    "babel-loader": "^8.1.0",
    "clean-webpack-plugin": "^3.0.0",
    "copy-webpack-plugin": "^6.0.3",
    "css-loader": "^4.0.0",
    "eslint": "^7.5.0",
    "eslint-loader": "^4.0.2",
    "file-loader": "^6.0.0",
    "html-webpack-plugin": "^4.3.0",
    "less-loader": "^6.2.0",
    "style-loader": "^1.2.1",
    "stylus-loader": "^3.0.2",
    "url-loader": "^4.1.0",
    "vue-loader": "^15.9.3",
    "vue-style-loader": "^4.1.2",
    "vue-template-compiler": "^2.6.11",
    "webpack": "^4.44.0",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0",
    "webpack-merge": "^5.0.9"
  },

webpack.common.js

//yarn add html-webpack-plugin --dev 自动生成HTML插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
//插件加载
const { VueLoaderPlugin } = require('vue-loader')

module.exports = {
    //打包入口文件
    entry: path.join(__dirname,'./src/main.js'),
    output: {
        //打包输出路径
        path: path.join(__dirname,'./dist'),
        //输出,
        filename: '[name].[hash:6].js'
    },
    //配置项通过别名来把原导入路径映射成一个新的导入路径
    resolve: {
        //在导入语句没带文件后缀时,Webpack 会自动带上后缀后去尝试访问文件是否存在
        extensions: ['.js', '.vue', '.json'],//用于配置在尝试过程中用到的后缀列表
        alias: {
            'assets':path.join(__dirname,'assets'),
            'pages': path.join(__dirname,'src/pages'),
            'public':path.join(__dirname,'public'),
            'components':path.join(__dirname,'src/components')
        }
    },
    module: {
        rules: [
            {
                //yarn add eslint-loader --dev
                test: /\.(js|vue)$/,
                use: 'eslint-loader',
                enforce: 'pre'
            }
        ]
    },

    plugins: [
        //自动生成HTML插件
        new HtmlWebpackPlugin({
            template: 'src/index.html',
        }),
        new VueLoaderPlugin()
    ]
}

webpack.dev.js

const webpack = require('webpack')
const {merge} = require('webpack-merge')
const baseConfig = require('./webpack.common.js')

module.exports = merge(baseConfig, {
  mode: 'development',
  devtool: 'cheap-module-eval-source-map',
  devServer: {
    clientLogLevel: 'warning',//日志级别
    hot: true,
    open: true,
    contentBase:path.join(__dirname,'./dist'),
    publicPath:'/',
   // overlay: { warnings: false, errors: true },
  },

  module: {
    rules: [
      {
          //css文件处理
        test: /\.css?$/,
        //执行顺序从右到左
        use: ['vue-style-loader','css-loader']
      },
      {
        test: /\.styl(us)?$/,
        use: ['vue-style-loader','css-loader', 'stylus-loader']
      },
      {
        test: /\.(js|vue)$/,
        use: 'eslint-loader',
        enforce: 'pre'
      }, {
        test: /\.less?$/,
        use: [
          'vue-style-loader',
          'css-loader',
          'less-loader'
        ]
      } ,{
        test: /\.vue$/,
        use: 'vue-loader'
      }, {
        test: /\.js$/,
        exclude: /node_modules/,//很重要
        use: {
          loader: 'babel-loader'
        }
      }, {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 10*1024,
            esModule: false,
          }
        }
      }, {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 10000,
          }
        }
      }, {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 10000,
          }
        }
      }
    ]
  },

  plugins: [
      //热更新
    new webpack.HotModuleReplacementPlugin()
  ]
})

webpack.dev.js

const merge = require('webpack-merge')
const baseConfig = require('./webpack.common')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const utils = require('./utils.js')

module.exports = merge(baseConfig, {
  mode: 'production',
  devtool: 'none',
  optimization: {
    usedExports:true,
    minimize:true,
    splitChunks: {
      cacheGroups: {
        commons: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendor',
          chunks: 'all'
        }
      }
    }
  },
  module: {
    rules: [
      {
        test: /\.css?$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader']
      },
      {
        test: /\.styl(us)?$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'stylus-loader']
      },
      {
        test: /\.(js|vue)$/,
        use: 'eslint-loader',
        enforce: 'pre'
      }, {
        test: /\.less?$/,
        use: [
          'vue-style-loader',
          'css-loader',
          'less-loader'
        ]
      } ,{
        test: /\.vue$/,
        use: 'vue-loader'
      }, {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          
        }
      }, {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 10*1024,
            esModule: false,
            name: utils.assetsPath('img/[name].[hash:7].[ext]')
          }
        }
      }, {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 10000,
            name: utils.assetsPath('media/[name].[hash:7].[ext]')
          }
        }
      }, {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 10000,
            name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
          }
        }
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(),
    new MiniCssExtractPlugin({
      filename: 'main.css'
    }),
    new CopyWebpackPlugin({
      patterns: [
        {
          from: utils.resolve('public/'),
          to: utils.resolve('dist/public'),
          toType: 'dir'
        }
      ]
    })
  ]
})

你可能感兴趣的:(拉钩教育,webpack)