All Projects → Faithree → web-build-tool-demo

Faithree / web-build-tool-demo

Licence: other
比较全面的前端构建工具demo,拿来即练,不定时更新,包含git npm gulp webpack babel typescript husky eslint tslint lint-stage prettier等

Programming Languages

javascript
184084 projects - #8 most used programming language
HTML
75241 projects
CSS
56736 projects

Projects that are alternatives of or similar to web-build-tool-demo

bradgarropy.com
🏠 my home on the web
Stars: ✭ 58 (+38.1%)
Mutual labels:  eslint, prettier
Typescript Express Starter
🚀 TypeScript Express Starter
Stars: ✭ 238 (+466.67%)
Mutual labels:  eslint, prettier
Eslint Config Wesbos
No-Sweat™ Eslint and Prettier Setup - with or without VS Code
Stars: ✭ 2,293 (+5359.52%)
Mutual labels:  eslint, prettier
Gatsby V2 Tutorial Starter
Gatsby V2 Starter - product of step by step tutorial
Stars: ✭ 139 (+230.95%)
Mutual labels:  eslint, prettier
generator-bunny
🐰 Jumpstart node module, like a bunny!
Stars: ✭ 13 (-69.05%)
Mutual labels:  eslint, prettier
Express Webpack React Redux Typescript Boilerplate
🎉 A full-stack boilerplate that using express with webpack, react and typescirpt!
Stars: ✭ 156 (+271.43%)
Mutual labels:  eslint, tslint
React Starter Kit
React, Redux, Webpack, Material UI, Boostrap 4, Code Splitting, HMR
Stars: ✭ 229 (+445.24%)
Mutual labels:  eslint, prettier
Lecture Frontend Dev Env
"[인프런] 프론트엔드 개발환경의 이해와 실습" 강의 실습 자료입니다.
Stars: ✭ 108 (+157.14%)
Mutual labels:  eslint, prettier
vue-antdesign-admin-template
Ant Design Pro Vue Template
Stars: ✭ 127 (+202.38%)
Mutual labels:  eslint, prettier
alda
A boilerplate for React isomorphic aplication with Material Design
Stars: ✭ 16 (-61.9%)
Mutual labels:  tslint, prettier
React Native Boilerplate
A React Native boilerplate with Expo, Redux, React Navigation, Styled Components and some 💕 included.
Stars: ✭ 135 (+221.43%)
Mutual labels:  eslint, prettier
typescript-api-starter
🔰 Starter for Node.js express API in Typescript 🚀
Stars: ✭ 72 (+71.43%)
Mutual labels:  eslint, prettier
Reeakt
A modern React boilerplate to awesome web applications
Stars: ✭ 116 (+176.19%)
Mutual labels:  eslint, prettier
Poetic
Automatically install and maintain ESLint, Prettier, EditorConfig and Airbnb rules for JavaScript, TypeScript and React.
Stars: ✭ 165 (+292.86%)
Mutual labels:  eslint, prettier
Zoe
🌀 Zero-config ESLint toolchain with sensible defaults.
Stars: ✭ 113 (+169.05%)
Mutual labels:  eslint, prettier
Codestyle
JavaScript and TypeScript Style Guide
Stars: ✭ 207 (+392.86%)
Mutual labels:  eslint, tslint
Simple React Calendar
A simple react based calendar component to be used for selecting dates and date ranges
Stars: ✭ 97 (+130.95%)
Mutual labels:  eslint, prettier
Typescript Eslint
✨ Monorepo for all the tooling which enables ESLint to support TypeScript
Stars: ✭ 10,831 (+25688.1%)
Mutual labels:  eslint, tslint
spec
🐣 easy to use eslint/stylelint/tslint/prettier/...
Stars: ✭ 60 (+42.86%)
Mutual labels:  tslint, prettier
figma-plugin-typescript-boilerplate
Figma plugin TypeScript boilerplate to start developing right away
Stars: ✭ 43 (+2.38%)
Mutual labels:  eslint, prettier

web-build-tool-demo

Build Status

本仓库持续更新

教程自动忽略命令行的形式,一律采用配置文件的方式,使用npm

安装

  • 进入每一个目录,npm install
  • 查看package.json 执行script里面的命令
  • 如果简单的demo没有命令,则npm install webpack -g
  • 有些命令是webpack3的 注意区分

Babel

npm install babel-loader babel-core babel-preset-env --save-dev   
index.js

document.write('<h1>乘风gg</h1>  ')
let func = () => {}
console.log([1, 2, 3].includes(3, 3));  // false

编译之后 发现includes是没被转换的,因为babel只编译语法,不会转换函数和方法(Array.from generator等),需要添加两个插件

npm install babel-polyfill --save-dev   

提取公共代码块

  • CommonsChunkPlugin,是多entry才会生效
  • 当你入口有多个,但无法区分哪个引入公共代码块,也不会生效(即需要所有入口都引入公共代码块,就可以自动抽离),需要手动指明name
  • CommonsChunkPlugin指定chunks

代码分割和懒加载

其实说的是同一件事情

require.ensure依赖promise,不兼容低版本浏览器

require.ensure(['vue'],function () { 
  // 第一个vue只是加载vue进页面(可以省略),只有第二个vue才真正执行
  var vue = require('vue')
},'vue'/*名字*/)
  • require.include 两个子模块依赖一个第三方模块的时候,可以提前把第三方模块放到父模块,这样动态加载子模块的时候就已经加载第三方模块,打包出来的结果是第三方模块在父模块里,类似commonChunk里面的async
  • system.import()->import()
  • import().then((vue)=>{}) publicPath:其实也是chunkHash模块对应的
 minChunks: ({resource}, count) => {
        console.log(resource)
        console.log(count)
      },
count指的是一个入口里面被使用的次数,当你多个entry里面的chunk引用多次,其实还是1次

动态import是会执行的,require.ensure是不会执行的

css

style-loader css-loader

url(link的方式)

 use: [
        {
          loader: 'style-loader/url',
        },
        {
          // loader: 'css-loader',
          loader: 'file-loader',
        }
      ],

useable(手动使用)

{
          loader: 'style-loader/useable',
        },
        {
          loader: 'css-loader',
        }

css module 预处理器sass/less 提取css(提取公共代码等)

less/scss

npm install less less-loader -D
npm install sass node-sass -D

extractTextPlugin

当入口文件前面有js,例如 './js/app': resolve(__dirname, './index.js'),
就要用下面这种方式
 filename: (getPath) => {
        return getPath('./css/[name].css').replace('./js/', '')
      }

postCss

postcss
post-loader
autoprefixer
cssnano
postcss-cssnext

css-loader内部压缩也是使用了cssnano post-loader要放在css-loader之后,放在预处理器语言之前

     {
            loader: 'postcss-loader',
            options: {
              ident: 'postcss',
              plugins: [
                require('postcss-cssnext')(),
                require('cssnano')(),
                require('postcss-cssnext')()
              ]
            }
          },

BrowserList配置

package.json里配置一份,所有插件都共用

 "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]

tree shaking

一般用在生产环境,支持es6 module 配合插件 使用场景:常规优化减小体积,引用第三方库的部分功能

js shaking

  • esm
  • webpack打包 (使用rollup打包JavaScript库支持esm导出,支持语法流程分析,用module,不然就是类似element的做法,或者说后编译)
  • 依赖性强
  • uglifyjs
  • babel(for...of 等)开启babel的loose模式

当引入第三方库不支持tree-shaking 的时候,先去找一找有没有es版本,假如还不支持,可以试试babel-plugin

css shaking

npm install purify-css -D
npm install purifycss-webpack -D
npm install glob-all  -D

purifyCss 要写在extractTextWebpackPlugin 后边 purifyCss 不能跟css module一起使用

image(优化)

  • 雪碧图
  • 压缩图片
  • base64
npm install url-loader img-loader file-loader postcss-sprites -D

因为生产环境和开发环境所依赖的地址是不一样的,或者说打包到一个独立的地方,所以最好配置一下

{
      test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
      use: [{
        loader: 'file-loader',
        options: {
          // publicPath: '',
          outputPath: 'dist/',
          useRelativePath: true
        }
      }]
    }

转base64

{
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        use: [{
          loader: 'url-loader',
          options: {
            name:'[name].min.[ext]',
            limit: 20000,
            // publicPath: '',
            outputPath: '/dist/',
            useRelativePath: true
          }
        }]
      }

图片压缩

  {
            loader: 'img-loader',
            options: {
              gifsicle: {
                interlaced: false
              },
              mozjpeg: {
                progressive: true,
                arithmetic: false
              },
              optipng: false, // disabled
              pngquant: {
                floyd: 0.5,
                speed: 2
              },
              svgo: {
                plugins: [
                  { removeTitle: true },
                  { convertPathData: false }
                ]
              }
            }
          },

合成雪碧图和打包retina屏幕的操作(需要把图片加上@2x,还要把容器缩小一半)

 {
            loader: 'postcss-loader',
            options: {
              ident: 'postcss',
              plugins: [
                require('postcss-sprites')({
                  spritePath:'dist/img/sprites',
                   retina: true
                })
              ]
            }
          }

处理字体

  {
        test: /\.(eot|woff2?|woff|ttf|svg)$/,
        use: [
          {
            loader: 'url-loader',
            options:{
              limit: 2000,
              outputPath: '/dist/',
              useRelativePath: true
            }
          }
        ]
      }

resolve

 resolve: {
    extensions: ['.js'],
    alias: {
      '~': resolve(__dirname, './comps')
    },
    modules: ['node_modules', resolve(__dirname, './my_modules')]
  }

alias

root:'d:' //子站公共的库

externals

配合provider插件可以实现cdn的功能 在一些场景下,例如自己手写一个库,并且引入了第三方库,则必须使用external引入第三方库,避免第三方库打包进自己的库

手写一个库

const webpack = require('webpack')
const { resolve } = require('path')

module.exports = {
  entry: resolve(__dirname, './index.js'),
  output: {
    path: resolve(__dirname, 'dist'),
    filename: '[name].js',
    library: 'myLib', // 使用的时候import mylib from 'mylib'
    libraryTarget: 'umd'
  },
  externals: {
    moduleExt: resolve(__dirname, './external_modules/ext_module.js')// 并不想把别人的库也打包进来,但是保留对这个库的引用
  }
}

调用 
import mylib from 'mylib'

引入第三方js库

  • webpack.providePlugin结合alias
  • imports-loader(自动)结合alias

自动生成html,可以自动插入css js

自动生成html

  new htmlWebpackPlugin({
      filename: 'index.html',
      template: './index.html',
      inject: true
    }),

引入图片

src="${require('路径')}“

或者用html-loader(可能会出现路径问题,因为他是跟url-loader相关联的)
   {
        test: /\.html$/,
        use: [
          {
            loader: 'html-loader',
            options: {
              publicPath: '',
              attrs: ['img:src', 'img:data-src']
            }
          }
        ]
      }

场景优化(让script标签减少http请求)

npm install html-webpack-inline-chunk-plugin

搭建web-server

  • webpack-dev-server
  • express-webpack-dev-middlewawre

webpack-dev-server是个很强大的工具,他就是一个简易的服务器,所以他有很多服务器的功能,例如接口代理,https,路径重定向,live reloading

contentBase功能类似打包后的路径,不过是从内存中读取,其实没什么鸟用,但是要用绝对路径

history模式

 historyApiFallback: {
      // 本质是connectHistoryApiFallback
      rewrites: [
        // 可以使用正则
        {
          from: '/example/index',
          to: '/index.html'
        }
      ]
    }

代理

proxy: {
      // 这里举例一个本地服务器的地址或者局域网内的地址
      '/api': {
        target: 'http://172.16.186.20:3000',
        host: 'http://localhost:8000',
        loglevel:'debug', // 代理信息
        changeOrigin: true,
        pathRewrite: {
          '/api': ''
        },
        headers:{
          // 一般用不上,主要用于未作登陆页面的测试页面
          // 伪造浏览器请求
          'Cookie':''
        }
      }
    }

模块热更新(这里很多误区)

 hot:true
 new webpack.HotModuleReplacementPlugin(),
 new webpack.NamedModulesPlugin()
 以上很多人认为都是热更新的,其实并不是。还要分情况
css热更新,假如使用了extract,页面是不会改变的(本质以来了satyle-loader),需要去除extract插件
js热更新需要加上hotOnly: true
并且代码内要使用module.hot来判断,通过module.hot.accept来热更新
合理使用accept的回掉函数进行移除和添加dom

sourceMap

  • js Devtool
  • css css-loader.option.sourcemap 所有的loader都加上sourcemap:true singleto:true要注释掉

eslint

npm install eslint eslint-loader eslint-plugin-html eslint-friendly-formatter --save-dev
npm install eslint-config-standard eslint-plugin-promise eslint-plugin-node eslint-plugin-import eslint-plugin-standard --save-dev

区分开发环境和生产环境

因为不同环境需要的功能是不一样的

  • 共同点

    • 相同入口
    • 相同loader
  • 开发环境

    • 模块热更新
    • sourceMap
    • eslint
    • proxy
  • 生产环境

    • 提取公共代码
    • 压缩代码
    • 混淆代码
    • tree shaking
npm install webpack-merge --save-dev

middleware

npm install express webpack-dev-middleware webpack-hot-middleware http-proxy-middleware opn connect-history-api-fallback --save-dev

打包分析

webpack -profile --json 结合http://webpack.github.io/analyse/
npm install webpack-bundle-analyzer

提高打包速度

  • dllPlugin DllReferencePlugin
  • new UglifyJSPlugin({ parallel: true, cache:true })
  • HappyPack
  • babel开启cache 规范include exclude
  • 减少resolve
  • 去除sourceMap
    new webpack.DllReferencePlugin({
      manifest:require('../src/dll/ui-manifest')
    }),
    new webpack.DllReferencePlugin({
      manifest:require('../src/dll/vue-manifest')
    }),

打包实践

动态模块要命名

路径问题

路径问题假如解决不了,一律用http服务器的思路去解决,直接指定跟目录'/'

loader

loader职责单一原则

自定义loader路径
 resolveLoader: {
    modules: ['node_modules', resolve(__dirname, 'loaders')]
  },

plugin

Compilation是从Compiler派生出来的(可以理解为继承),并且会携带一些构建时候加入的东西

补充(一个新的脚手架工具)

全局安装webpack-cli

npm install webpack-cli -g

作用:

  • Creating new webpack projects(交互式创建项目)
  • Migration from webpack v1 to v2(升级迁移版本)

webpack 4 beta

npm install webpack webpack-cli --save-dev

不需要任何的配置文件,直接输入命令npm start就可以打包到/dist/main.js,默认mode:production

打包结果输出不一样 webpack3以前是一个自执行函数,参数是一个数组,数组的作用就是顺序递归调用每一个函数,根据数组的索引,最后结束时还是第一个函数 而webpack4的自执行函数不再是数组了,而是一个对象,键的一个路径,递归调用也明显不再是根据id来调用了,而是根据这个键,个人觉得键值对的方式更好,因为webpack3之前是一个排好序的数组,这个数组排序,尤其是多层嵌套的情况下,应该是比较消耗性能的

总结

  1. 编译 打包 hmr 代码分割 文件处理
  2. tree shaking es module 动态import
  3. scope hoisting(打包以后性能提升) magic comments 4.Mode, 零配置以及默认值
webpack 4之前,js 是 webpack 中的唯一模块类型,因而不能有效地打包其它类型的文件。而 webpack 4 则提供了 5 种模块类型:
 module: {
    rules: [{
        test: /\.special\.json$/,
        type: "javascript/auto",
        use: "special-loader"
    }]
 }

手写webpack

npm link

splitChunk

spa的话直接用node_modules那一套就可以匹配,多页面尽量用all自动配置,抽离的话就在下面加组,一个页面里面需要分离多个Chunks的话priority会影响打包生成的chunk的(试试demo),一般来说公共库第一,基础库紧跟其后,但是不一定,顺序可以调一下,总的来说这个插件有点坑,可配置性太差了

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].