原生前端项目工程化改造

284 阅读4分钟

代码

一.webpack学习

  1. webpack核心概念
    mode: 模式
    entry:入口模块文件路径
    output:输出bundle文件路径
    module:模块,webpack构建对象
    bundle:输出文件,webpac构建产物
    chunk:中间文件,webpack构建的中间产物
    loader:文件转换器(例如转换.vue文件)
    plugin:插件,执行特定任务

2.quick start

1.npm init 初始化项目
2.创建src/index.js
3.创建publish/index.html
4.创建webpack.config.js,并填入配置
5.安装webpack webpack-cli
6.npm配置build命令
7.执行npm run build 完成打包构建

3.source-map分析

   mode:development devtool:none 不会单独生存source-map 映射文件都会在bundle.js里面
   浏览器会自动解析

# JavaScript Source Map 详解 4.loader

    //config loader运行顺序从右到左 从下到上
    module:{
        rules: [
            {
                test: /\.css$/,
                use:['style-loader','css-loader']
            },
            {
                test: /\.test$/,
                use;[path.resolve(__dirname,'./xxx/xxx-xxx.js')]
            }
        ]
    }
   //my-loader.js
    module.exports = (source) => {
        let newSource = source
        //do something
        return newSource
    }
    

5.plugins

   //config 也有执行顺序,不过一般都会写在执行的生命周期触发
       plugins: [new XXXXPlugins(options)]
  // my-plugin.js
     const pluginName = xxxx
    class Myplugin {
        constructor(options){}
        apply(compiler) {
            compiler.hooks.xxx.tap(pluginName,compilation => {
                compilation.hooks.xxx.tap(pluginName,() => {
                    //do something
                })
            )
        }
    }

二.前端项目工程化改造

1.初始化webpack配置

    // npm init -y
    // cnpm i webpack webpack-cli style-loader css-loader -D
    //配置webpack.config.js

2.配置多入口,多页面,处理图片,垫片,不同分别引入不通的js

   //改造index 和login页面 需要配置多入口
       entry: {
        index: './src/index.js',
        login: './src/login.js'
      },
  //处理图片
       module: {
        rules: [
          {
            test: /\.css$/,
            use: ['style-loader', 'css-loader']
          },
          {
            test: /\.(png|svg|jpg|jpeg|gif)$/i,
            type: 'asset',
            parser: {
              dataUrlCondition: {
                maxSize: 8 * 1024
              }
            },
            generator: {
              filename: 'images/[name].[hash:6][ext]'
            }
          }
        ]
  },
  //配置ProvidePlugin 垫片作用:自动加载,而不必模块import或require它们无处不在 
     new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    })
  //多页面多模版 引入不通的js需要用htmlWebpackPlugin的chunks
      new htmlWebpackPlugin(
      {
        template: path.resolve(__dirname, './src/index.html'),
        filename: 'index.html',
        chunks: ['index']
      }
    ),
    new htmlWebpackPlugin(
      {
        template: path.resolve(__dirname, './src/login.html'),
        filename: 'login.html',
        chunks: ['login']
      }
    ),
  

3.优化

     //每次改动都要重新build 这里使用webpack-dev-server(只是在内存中储存打包好的文件,物理上dist目录不会生成,修改完然后还需要build)
     //cnpm i webpack-dev-server -D
    //由于html模版里的图片没有处理,直接把图片拷贝到dist目录
      devServer: {
        static: {
          directory: path.join(__dirname, 'dist')
        },
        compress: true,
        port: 9000,
        hot: true
     },
    // cnpm i copy-webpack-plugin -D
     new CopyWebpackPlugin({
      patterns: [{
        from: path.resolve(__dirname,'./src/img'),
        to: path.resolve(__dirname,'./dist/img')
      }]
    })
    //剥离css
    //cnpm i min-css-extract-plugin -D
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader']
      },
     new MiniCssExtractPlugin({
      filename: 'css/[name].css',
      chunkFilename: 'css/[name].chunk.css'
    })
   //压缩css js
   //cnpm i css-minimizer-webpack-plugin uglifyjs-webpack-plugin
    optimization: {
        minimize: true,
        minimizer: [
          new UglifyJsPlugin({ sourceMap: true }),
          new CssMinimizerPlugin()
        ]
  },
    //treeshaking
    //1.解构引入
    //2.只支持esmodule
    //3.mode模式必须是production
//前提 splitChunks不处理业务代码里面的模块 不在node_modules下的同步包都打进index.js
//如果不配置splitChunks,会把所有同步包都打到index.js 异步包单独打成一个个单独的js
//配置splitChunks 只针对node_modules下
//先处理cacheGroups,然后再处理外面的chunks cacheGroups每个选项没设置都设置上面总的
-   `chunks`选项,决定要提取那些模块。

    -   默认是`async`:只提取异步加载的模块出来打包到一个文件中。

        -   异步加载的模块:通过`import('xxx')``require(['xxx'],() =>{})`加载的模块。

    -   `initial`:提取同步加载和异步加载模块,如果xxx在项目中异步加载了,也同步加载了,那么xxx这个模块会被提取两次,分别打包到不同的文件中。

        -   同步加载的模块:通过 `import xxx``require('xxx')`加载的模块。

    -   `all`:不管异步加载还是同步加载的模块都提取出来,打包到一个文件中。

-   `minSize`选项:规定被提取的模块在压缩前的大小最小值,单位为字节,默认为30000,只有超过了30000字节才会被提取。

-   `maxSize`选项:把提取出来的模块打包生成的文件大小不能超过maxSize值,如果超过了,要对其进行分割并打包生成新的文件。单位为字节,默认为0,表示不限制大小。

-   `minChunks`选项:表示要被提取的模块最小被引用次数,引用次数超过或等于minChunks值,才能被提取。

-   `maxAsyncRequests`选项:最大的按需(异步)加载次数,默认为 6。

-   `maxInitialRequests`选项:打包后的入口文件加载时,还能同时加载js文件的数量(包括入口文件),默认为4。

-   先说一下优先级 `maxInitialRequests` / `maxAsyncRequests` <`maxSize` <`minSize`。

-   `automaticNameDelimiter`选项:打包生成的js文件名的分割符,默认为`~`。

-   `name`选项:打包生成js文件的名称。

-   `cacheGroups`选项,核心重点,**配置提取模块的方案**。里面每一项代表一个提取模块的方案。下面是`cacheGroups`每项中特有的选项,其余选项和外面一致,若`cacheGroups`每项中有,就按配置的,没有就使用外面配置的。

    -   `test`选项:用来匹配要提取的模块的资源路径或名称。值是正则或函数。
    -   `priority`选项:方案的优先级,值越大表示提取模块时优先采用此方案。默认值为0。
    -   `reuseExistingChunk`选项:`true`/`false`。为`true`时,如果当前要提取的模块,在已经在打包生成的*js*文件中存在,则将重用该模块,而不是把当前要提取的模块打包生成新的*js*文件。
    -   `enforce`选项:`true`/`false`。为`true`时,忽略`minSize``minChunks``maxAsyncRequests``maxInitialRequests`外面配置选项。
    
    splitChunks: {
      minSize: 30 * 1024,
      name: 'chunk',
      chunks: 'all',
      cacheGroups: {
        jq: {
          test: /jquery\.js/,
          name: 'jq',
          chunks: 'all'
        },
        flex: {
          test: /flexslider\.js/,
          name: 'flex',
          chunks: 'all'
        }
      }
    }
    //使用ejs和clean
    //cnpm i ejs-loader clean-webpack-plugin -D

三.前端项目工程化vue改造

1.移动webpack.config.js文件

    //注意里面的配置的路径也要改变
    //package.json里面加上 --config ./build/weback.config.js

2.初始化vue2改造

   //1.创建main.js app.vue /public/index.html
   //2.创建webpack.vue.config.js copy过来一份 修改
   //3.安装vue@2.6.14 vue-loader@15.9.8 vue-template-compiler@2.6.14
   //4.创建命令 start:vue build:vue
   //注意启动webpack-dev-server UglifyJsPlugin不能用soureMap:true

3.首页和登录页移植

  //1.安装vue-router^3.5.3
  //2.按照vue修改组件

4.SPA改造成MPA

    //1.创建webpack.vue.mpa.config.js copy过来一份 修改
    //2.创建命令 start:vuempa build:vuempa

5.vue2升级成vue3

    //1.安装最新的vue和vue-loader vuerouter
    //2.按照vue3的语法修改项目