【Webpack技巧】

node-sass高node版本下异常

在高版本的node中,node-sass停止使用,需要更换为sass,但是/deep/语法无法被支持,需要更换为::v-deep
解决方案1:降node版本,考虑通过nvm管理多版本,保持代码不变
解决方案2:更换依赖,全局替换字符串,代码修改范围大
解决方案3:更新依赖,自定义loader处理源码

新建一个文件css-deep-loader.js

module.exports = (source, map, meta)=> {
  if (/\/deep\//g.test(source)) {
    // 如果你想更完善,可以在正则中匹配
    source = source.replace(new RegExp(/\/deep\//, 'g'), '::v-deep ');
  }
  return source;
};

在webpack.conf.js中引入

module:{
  rules:[{
    test: /\.vue$/,
      loader: path.resolve(__dirname, './css-deep-loader.js')
  }]
}

注意:

  1. loader的执行顺序是从下到上的,为了让这个loader最先执行,把这个loader放在vue-loader之下
  2. __dirname是当前脚本的目录,是node全局变量,使用__dirname避免路径加载异常

webpack常用启动配置说明

  1. 热更新:
    1. 当代码修改后,我们希望页面能及时更新,而不是重启应用,这时就需要用到热更新。如果开启了热更新,webpack-dev-server启动服务(启动命令在package.json中)后,打开链接,浏览器与服务器间建立一个websocket双向通信渠道,如果代码更新,那样服务器会向浏览器推送更新内容,打开控制台,查看Network,可以看到接收的信息,从而触发页面更新。

  1. 使用说明:
    1. 在启动命令中设置–inline,这意思着代码更新时刷新整个页面
    2. –hot则只更新涉及的组件,如果同时设置有–inline和–hot,那么–hot会先生效,如果–hot失败,则触发–inline,直接刷新整个页面
    3. 以上两种命令也可以直接写在配置文件中
    4. 更多原理可以查看webpack模块热替换,另外,为了解析.vue文件,使用了vue-loader,内部使用了vue-hot-reload-api,添加–hot参数会自动启动热更新,vue热重载可以查看vue-loader热重载
  entry{}
  devServer:{
    hot:true,
    inline:true
  },
  plugins:[]
  1. webpack-merge:webpack配置整合,webpack配置的本质是把编译命令行上的参数通过配置的方式载入
    1. 项目开发一般会有开发环境和正式环境,为此需要设置不同的配置文件
      1. webpack.base.conf.js:设置共有的配置项目,如项目入口、出口、别名、loader,一些差异较小的内容可以通过判断环境(dev/production)来设计
      2. webpack.dev.conf.js:设计开发环境需要用到的配置,例如开发环境需要开启本地服务、热更新;前后端共同开发的项目可能还需要设置代理,解决跨域问题;本地开发需要调试、debug,需要保留源码格式,需要开启sourceMap
      3. webpack.prod.conf.js:打包生产环境用到的配置,为了提高首次加载速度,需要进行分包;也不需要保存源码格式,减小包体积;同时使用插件对代码进行压缩,进一步缩小体积
    2. 在webpack.dev.conf.js/webpack.prod.conf.js中引入webpack.base.conf.js,通过webpack-merge进行整合,冲突的内容会以后者为准
  2. path:通过require引入,在配置文件中直接使用相对路径会出错,可能是由于命令实际执行的路径与配置文件不一致,解析配置文件的相对路径就无法获取到正确的资源,所以通过path.resolve(__dirname, filePath)来设置文件路径,__dirname是node的全局变量,会指向正在执行的脚本的目录
  3. 别名:让引入变得更简单
    1. 在加载静态资源时,可能因为相对路径要写很多‘…/’,效率很低,还容易出错,通过别名,将@配置为根路径,直接使用src=’@/assets/.png’,在css中background: url(~@/assets/images/right_arrow_icon.png);
    2. 代码:
module.exports = {
	resolve: {
		alias: {
			‘@’: path.resolve(__dirname, 'src'),
		},
	},
};
  1. vue-loader
    1. 处理.vue文件,vue主要有三个块,template\script\style,style可能用不同的语言,如css\sass\less等,所以需要配置对应的loader来处理
    2. 把css提取出来需要配合ExtractTextPlugin
  2. portfinder:端口扫描,可能已经启动的服务占用了端口,自动搜索可用的端口
  3. HtmlWebpackPlugin:webpack打包会把所有文件打包成一个js文件,那么这个js文件如果生效呢,答案就是这个插件,它能自动生成html文件,或者按指定模板生成,然后把生成的js\css文件引入其中
  4. 代码分离:webpack打包后生成一个js文件,直接引入html中,这可能导致首次加载出现白屏,js下载时间过长,有没有什么办法只加载需要的内容呢?最简单的方案是直接配置多个入口文件、分模块,这会导致模块内容重复,也不够灵活,更好的方案是动态导入。静态导入是直接在文件头中import模块/组件,这意味着所有模块都会被构建到webpack的出口js文件中,导致js文件过大。动态导入会延迟加载,import(pathname)返回一个Promise对象,在真正使用时才会去加载,vue Router中懒加载使用component:()=>import(pathname)就是这个原理,更多内容见webpack代码分离
  5. CommonsChunkPlugin:分离三方库、公共文件、运行时文件,上面的代码分离是逻辑上的分离,是组件的分离,而此插件的分离是chunk的分离,是多入口文件的分离(配置了多个entry),提取公共文件
  6. DefinePlugin:设置应用全局变量,例如网络请求时,开发环境与正式环境请求后端的接口不一样,可以根据环境还设置对应的值

自动配置启动IP

H5开发经常需要运行在手机端,有时可能需要在三方平台上测试,或者在手机上开发调试,如果使用localhost就无法访问,每次查IP,然后更改比较麻烦,可以考虑自动获取

function getIpAdress () {
  const interfaces = require('os').networkInterfaces()
  for (const devName in interfaces) {
    const iface = interfaces[devName]
    for (let i = 0; i < iface.length; i++) {
      const alias = iface[i]
      if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
        return alias.address
      }
    }
  }
}

用IP访问可以会导致复制API(Clipboard)失效

你可能感兴趣的:(webpack,前端)