前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >webpack从零搭建开发环境

webpack从零搭建开发环境

作者头像
小丑同学
发布2020-09-21 11:10:46
1.2K0
发布2020-09-21 11:10:46
举报
文章被收录于专栏:小丑的小屋小丑的小屋

什么是 webpack

使用 webpack 作为前端构建工具

  • 代码转化:TypeScript编译成Javascript,SCSS编译成Css
  • 文件优化:压缩JavaScriptCssHtml代码 压缩合并图片等
  • 代码分割:提取多个页面的公共代码 提取首屏不需要执行部分的代码让其异步加载
  • 模块合并:在采用模块化的项目会有很多个模块和文件,需要构建功能把模块分类合并成一个文件
  • 自动刷新:监听本地源代码的变化,自动重新构建,刷新浏览器
  • 代码校验:在代码被提交到仓库前需要校验代码是否符合规范,以及单元测试是否通过
  • 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统

在 webpack 应用中有两个核心

  • 模块转换器:用于把模块原内容按照需求转换成新内容,可以加非 JS 模块
  • 扩展模块:在 webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做 NIIT 想要的事情

初始化项目

npm init -y
npm i webpack webpack-cli --save-dev
npm -S 是--save的缩写  是生产
npm -D 是--save-dev的缩写  是开发

webpack-cli 的目的是解析用户传递一些参数给 webpack 打包

打包

  • webpack 默认支持模块的写法 commonJs 规范是 Node
  • 也支持 es6 规范 esmodule
  • 把模块打包,解析出浏览器可以识别的代码
  • webpack 的时候是装的开发环境 直接 webpack 是找不到的,可以使用 npx (这个命令是 npm 5.2) 之后出来的 npx 是默认找 node_modules 中的.bin 目录下的文件
  npx webpack
  • 两种模式:开发环境 生产环境
  npx webpack --mode development  开发环境不会被压缩

为了方便也可以这么写,使用 npm run 命令这个命令执行的时候默认会把 node_modules 的.bin 文件放到全局上,执行之后销毁npm run buildnpm run dev

  "scripts": {
  	"build":"webpack --mode production",
  "},
  • webpack 配置文件默认叫 webpack.config.js webpack.file.js

默认导出的是配置文件

  • 入口
module.exports={ //入口 entry:path.resolve(__dirname,'./src/index.js'), //写路径都采用绝对路径 }
  • 出口
module.exports={ output:{ filename:"bundle.js", path:path.resolve(__dirname,"dist"); } }
  • 模式
module.exports = { mode: "development" //当前是开发模式 }
"scripts": { "build": "webpack", "dev":"webpack" }, //- 变量的形式

webpack.config.js

module.exports = (env)=>{ //env 环境变量 console.log("mode",env) //函数要返回配置文件,没返回会采用默认配置 }

package.json

"scripts": { "build": "webpack --env.production", "dev":"webpack --env.development" },

为了区分开发模式和生产模式 会新建一个 build 文件 新建一个基础配置 webpack.base.js

webpack.base.js webpack.dev.js webpack.prod.js通过--config 指定执行的文件是哪一个。

  • 可以在 base 文件合并
  • 可以创建 dev,prod 分别在这两个文件中合并 base
"scripts": {
    "build": "webpack --env.production --config ./build/webpack.base.js",
    "dev": "webpack --env.development --config ./build/webpack.base.js"
},
  • 可以通过 webpack-merge 来合并配置文件
npm i webpack-merge --save-dev

用法

if(isDev){
  return merge(base,dev)
}else{
  return merge(base,prod)
}

如果是开发环境,要使用 webpack-dev-server

npm i webpack-dev-server --save-dev

webpack-dev-server 是在内存中打包的不会产生实体

 "scripts": {
    "build": "webpack --env.production --config ./build/webpack.base.js",
    "dev": "webpack-dev-server --env.development --config ./build/webpack.base.js"
  },
module.exports={
    mode:"development",
    devServer:{  //开发服务的配置
       port:3000,
       compress:true, //gzip 可以提升返回页面的速度
       contentBase:path.resolve(__dirname,'../dist') //webpack启动服务会在dist目录下
    }
}
  • 在 dist 打包自动生成 html 文件并且引入打包后的 js 内容
npm i html-webpack-plugin --save-dev

在根文件下创建 public 文件夹

 plugins:[
         new HtmlWebpackPlugin({
             template:path.resolve(__dirname,'../public/index.html'),
             filename:"index.html",
             minify:!isDev&&{
                 removeAttributeQuotes:true,  //去掉双引号
                 collapseWhitespace:true   //去掉空格
            }
         })
     ]
  • 每次打包重新生成 dist
npm i clean-webpack-plugin --save-dev
  //每次打包先清空dist文件夹
  new CleanWebpackPlugin({
       cleanOnceBeforeBuildPatterns: ['**/*']   //打包之前清空目录  默认是这个配置  所有目录下的所有文件
  }),

代码转化

css

先解析 css

// index.js
import './index.css'
//引入css

1.loader 的执行顺序 默认从下往上执行 从右往左执行

2.css-loader 会解析 css 语法 style-loader 会将解析的 css 变成 style 标签插入到页面中

3.解析 css 需要两个 css-loader style-loader

npm i css-loader style-loader --save-dev
转化什么文件 用什么去转  使用那些loader
loader写法 可以是[] 也可以是{}也可以是""
rules:[
  {
   test:/\.css$/,
   use:['style-loader','css-loader']
  },
]

预处理器

scss node-sass sass-loader

npm i node-sass sass-loader --save-dev
匹配到scss结尾的文件使用sass-loader来调用node-sass处理sass文件
{
test:/\.scss$/,
use:['style-loader','css-loader','sass-loader']
}

less less-loader

stylus stylus-loader

如果 css 里引入了 scss 文件

rules:[
  {
    test:/\.css$/,
    use:['style-loader',{
      loader:'css-loader',
      options:{
          importLoaders:1
      }
    },'sass-loader']
  },
]

css 加前缀

  • 自动加前缀
npm i postcss-loader --save-dev
 npm i autoprefixer --save-dev

需要一个配置文件 post.config.js

module.exports={
    plugins:[
        require("autoprefixer")
    ]
}

创建一个.browserslistrc 文件

cover 95%
  • 这么写开发是 ok 的,但是怎么解决生产样式?
    • 解析 css 的时候就不能渲染 dom
    • 希望 css 可以和 js 一起加载 mini-css-extract-plugin 需要把 css 抽离
npm i mini-css-extract-plugin --save-dev
new MiniCssExtractPlugin({  //如果是开发模式就不要用抽离样式的插件
    filename:"css/main.css"
})
{
  test: /\.css$/,
  use: [
    isDev?'style-loader':MiniCssExtractPlugin.loader,
     {
    loader: 'css-loader',
    options: {
      importLoaders: 2
    }
  }, 'postcss-loader', 'sass-loader']
}

webpack.prod.js

const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
module.exports={
    mode:"production",
    optimization: {  //优化项
        minimizer:[  //可以放置压缩方案
            new OptimizeCSSAssetsPlugin(),  //用了这个 js也得手动压缩
            new TerserJSPlugin()
        ]
    },
}

图片

  • 压缩图片
 npm i file-loader --save-dev
 npm i url-loader --save-dev
{
	test:/\.(woff|ttf|eot|svg)/,
	use:"file-loader"
},
{
	test: /\.(jpe?g|png|gif|jpg)$/,
	use: {
		loader: "url-loader",
		//如果大于100k的图片继续使用file-loader
		options: {
			name: 'image/[contentHash].[ext]',
			limit: 100 * 1024
		}
	}
	//file-loader  默认的功能是拷贝的功能
	//我希望是当前比较小的转化成base64 比以前大 好处就是不用发http请求
}

js

  • es6es5 但是有些 api 不是 es6 语法比如装饰器 类的属性
  • babel 转化功能 vue-cli 基于 babel6 来实现的,但是现在最新 babel 是 babel7
    • @babel/core 核心模块
    • @babel/preset-env 把 es6 转化成 es5
    • babel-loader 是 babel 和 webpack 的桥梁

总结:默认会调用@babel/core 来转化代码 转化的时候用@babel/preset-env 将 es6 转化成 es5

  { //解析js文件 调用@babel/core
      test:/\.js$/,
      use:"babel-loader"
  },
  • 创建 .babelrc文件默认是 options 的配置
{
    "presets:[
        "@babel/preset-env"  //从下到上执行 这个是插件包
    ],
    "plugins":[  //从上到下执行   这个是单个插件

    ]
}
  • 解析提案语法 类的属性
npm i @babel/plugin-proposal-class-properties -D
"plugins":[  //从上到下执行
       ["@babel/plugin-proposal-class-properties",{"loose":true}]
    ]
  • loose:true 表示宽松 this.a=1
  • loose:false Object.definedProperty

解析装饰器

npm i @babel/plugin-proposal-decorators --save-dev
  • 必须在@babel/plugin-proposal-class-properties 上面执行
"plugins":[  //从上到下执行
       ["@babel/plugin-proposal-decorators",{"legacy":true}],
       ["@babel/plugin-proposal-class-properties",{"loose":true}]
    ]
  • 解析高级语法 使用的 api 自动转化 并且是按需加载
"presets":[
        ["@babel/preset-env",{
            "usageBuitIns":"usage"   //按需加载
        }]  //从下到上执行
    ],
  • 节约代码大小
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime

解析jsx

npm i @babel/preset-react --save-dev

解析ts

  • ts-loader 使用 typescript
  • babel7 @babel/preset-typescript 和 typescript 库没有关系
npm i typescript
npx typescript -init 生成一个typescript文件

解析vue

  • vue.shims.d.ts
declare module "*.vue"{
    import Vue from "vue";
    export default Vue
}
npm i vue-loader vue-template-compiler -D
{
	test:/\.vue$/,
	use:"vue-loader"
},
const VueLoaderPlugin = require("vue-loader/lib/plugin");
new VueLoaderPlugin(),
  • vuets
npm i vue-property-decorator --save-dev
["@babel/preset-typescript",{
	"allExtensions":true
}]

最后

了解了上面的这些webpack,基本上就可以搭建我们的开发环境了,本文结束,有什么问题和有错误的地方,欢迎大家的留言和评论,还有后续更新,下期更加精彩

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小丑的小屋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是 webpack
  • 初始化项目
  • 打包
    • 用法
    • 代码转化
      • css
        • css 加前缀
          • 图片
            • js
              • 解析jsx
                • 解析ts
                  • 解析vue
                    • 最后
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档