用 webpack 4.0 撸单页/多页脚手架 (jquery, react, vue, typescript)

1.导语

        首先来简单介绍一下webpack:现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个会映射项目所需的每个模块 的依赖图(dependency graph),并生成一个或多个 bundle。webpack4.0出现之后,我们可以不用再引入一个配置文件来打包项目,并且它仍然有着很高的可配置性,可以很好满足我们的需求。 在开始正文之前,首先先来看看我们要实现的成果:

  • 支持ES6+JQuery+Less/Scss的单页/多页脚手架
  • 支持ES6+React+Less/Scss+Typescript的单页/多页脚手架
  • 支持ES6+Vue+Less/Scss+Typescript的单页/多页脚手架

github地址:

基于webpack4.0搭建的脚手架(支持react/vue/typescript/es6+/jquery+less/scss)

在脚手架的开发过程中我会详细介绍每个插件或者loader的用途以及webpack的核心理念,如有不懂或者有其他更好的想法欢迎交流。 下面是基于该文章的webpack4.0的思维导图:

2.webpack核心概念

  • 入口:指示 webpack 应该使用哪个模块作为入口起点
  • 输出:告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件
  • loader:让 webpack 能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用
  • 插件:用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量
  • 模式:通过选择 development, production 或 none 之中的一个,来设置 mode 参数,从而进行不同的打包优化
  • 浏览器兼容性:支持所有符合ES5 标准的浏览器(不支持 IE8 及以下版本) 下面提供官网的打包模型

3.支持ES6+JQuery+Less/Scss的单页/多页脚手架

在实现脚手架之前,假设我们已经创建了目录和package.json文件,接下来先安装webpack相关依赖:

1// 此处建议安装局部依赖,安装全局依赖可能会出现版本问题 2npm install -D webpack webpack-cli

因为项目要支持es6+,我们还需要安装babel相关依赖:

1npm install -D babel-loader @babel/core @babel/preset-env

这个时候可以开始配置我们的脚手架逻辑了,为了项目结构清晰易于维护,我们建一个build目录专门放webpack构建的脚本,webpack默认的配置文件是webpack.config.js,由于实际项目需要,我们将其拆分为3个文件,分别是webpack通用配置文件webpack.base.js,开发环境配置文件webpack.dev.js以及生产环境配置文件webpack.prod.js。 image.png 我们先处理webpack.common.js文件

1const path = require('path'); 2const webpack = require('webpack'); 3 4module.exports = { 5 entry: { 6 main: './src/index.js', 7 }, 8 output: { 9 path: path.resolve(__dirname, '../dist'), 10 }, 11 module: { 12 rules: [ 13 // 将es6编译成es5 14 { 15 test: /\.jsx?$/, // ?表示x有0个或一个 16 exclude: /node_modules/, // 不编译某个目录下的文件 17 include: path.resolve(__dirname, '../src'), // 只在include包含的目录下进行loader编译 18 use: [ 19 "babel-loader", 20 ] 21 }, 22 ] 23 } 24}

为了项目后期的开发和维护,我们建立好项目结构: image.png

public目录是事先准备好的html模版,这里就不介绍了,其他目录可根据具体项目进行设置。

我们还需要一个插件将打包后的文件植入到html模版中并导出到dist目录下,这里使用html-webpack-plugin来实现

1npm install -D html-webpack-plugin

现在webpack.base.js为如下:

1const path = require('path'); 2const HtmlWebpackPlugin = require('html-webpack-plugin'); 3const template = path.resolve(__dirname, '../public/index.html'); 4 5module.exports = { 6 entry: { 7 main: './src/index.js' 8 }, 9 output: { 10 path: path.resolve(__dirname, '../dist') 11 }, 12 module: { 13 rules: [ 14 // 将es6编译成es5 15 { 16 test: /\.jsx?$/, // ?表示x有0个或一个 17 exclude: /node_modules/, // 不编译某个目录下的文件 18 include: path.resolve(__dirname, '../src'), // 只在include包含的目录下进行loader编译 19 use: [ 20 "babel-loader", 21 ] 22 }, 23 ] 24 }, 25 plugins: [ 26 new HtmlWebpackPlugin({ 27 template, 28 filename: 'index.html' 29 }) 30 ] 31}

为了打包项目,我们需要在webpack.prod.js目录下进行配置,此处需要一个模块webpack-merge将wepack基础配置合并进生产配置,我们先来安装一下:

1npm install -D webpack-merge

webpack.prod.js配置如下:

1const merge = require('webpack-merge'); 2const base = require('./webpack.base'); 3 4module.exports = merge({ 5 mode: 'production', 6 output: { 7 filename: 'js/[name]_[contenthash].js', // 入口和内容hash组成的文件名,也可以是hash 8 chunkFilename: 'js/[name]_[contenthash].chunk.js' 9 } 10}, base)

然后在package.json里添加执行脚本:

1"scripts": { 2 "build": "webpack --config ./build/webpack.prod.js" 3 }

webpack默认会找名为webpack.config.js的文件,由于我们将其拆解为prod和dev,所以我们要手动指定webpack执行的文件,添加--config,即可手动指定目录。下面我们开始写一段代码试试吧,在index.js中写入如下es6代码:

1// index.js 2let name = 'xuxi'; 3let say = (name) => { 4 alert(name) 5}; 6say(name);

下面我们执行:

1npm run build

此时我们会看见项目中多了一个dist目录,里面的html也植入了相应的代码, image.png 在浏览器中打开: image.png ok,第一步完成。 下一步是支持css,我们先安装如下几个模块:

1npm install --save-dev css-loader style-loader

在webpack.base.js中的module中添加如下代码:

1module: { 2 rules: [ 3 // 将es6编译成es5 4 { 5 test: /\.jsx?$/, // ?表示x有0个或一个 6 exclude: /node_modules/, // 不编译某个目录下的文件 7 include: path.resolve(__dirname, '../src'), // 只在include包含的目录下进行loader编译 8 use: [ 9 "babel-loader", 10 ] 11 }, 12 // 加载css 13 { 14 test: /\.css$/, 15 use: ['style-loader', 'css-loader'], 16 }, 17 ] 18 }

注意,laoder的加载顺序是从下往上,从右往左的,所以配置loader的时候要注意一下顺序。 此时在styles目录下加入app.css,在js中引入:

1// app.css 2#root { 3 background-color: #f0c; 4 height: 100px; 5} 6 7// index.js 8import './styles/app.css'

此时打开浏览器,可以看到css生效了: image.png 现在css导入虽然生效了,但是是有js动态创建添加到head里面的,如果后期项目复杂了,将会严重影响项目的加载速度,所以我们这里需要另一个插件,对css进行代码分割,单独生成css文件:

1npm isntall mini-css-extract-plugin -D

根据该插件的官方配置,我们需要把style-loader替换成该插件提供的loader,并配置导出的css文件目录和文件名,为了提高开发环境构建速度,我们只在生产环境分割css:

1// webpack.prod.js 2const merge = require('webpack-merge'); 3const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 4const base = require('./webpack.base'); 5 6module.exports = merge({ 7 mode: 'production', 8 output: { 9 filename: 'js/[name]_[contenthash].js', // 入口和内容hash组成的文件名,也可以是hash 10 chunkFilename: 'js/[name]_[contenthash].chunk.js' 11 }, 12 module: { 13 rules: [ 14 { 15 test: /\.css$/, 16 use: [ // loader解析的顺序是从下到上,从右到左的顺序 17 { 18 loader: MiniCssExtractPlugin.loader, 19 options: { 20 filename: '[name].css', 21 chunkFilename: '[name].css', 22 publicPath: '../' //****最后打包的时候替换引入文件路径 23 }, 24 }, 25 // 'style-loader', 使用MiniCssExtractPlugin时就不能使用style-loader了 26 { 27 loader: 'css-loader', 28 options: { 29 importLoaders: 2 //该方式可以让@import引入的css文件再次执行一边css打包loader 30 } 31 }, 32 ] 33 } 34 ] 35 }, 36 plugins: [ 37 new MiniCssExtractPlugin({ 38 // Options similar to the same options in webpackOptions.output 39 // both options are optional 40 filename: 'css/[name]_[hash].css', 41 chunkFilename: 'css/[name]_[hash].chunk.css', 42 }), 43 ] 44}, base)

由于我们在dev和prod环境的css-loader不一样,所以我们将base的css-loader配置删除,移到dev下

1// webpack.dev.js 2const base = require('./webpack.base'); 3const merge = require('webpack-merge'); 4const webpack = require('webpack'); 5 6module.exports = merge({ 7 mode: 'development', 8 module: { 9 rules: [ 10 { 11 test: /\.css$/, 12 use: [ // loader解析的顺序是从下到上,从右到左的顺序 13 'style-loader', //使用MiniCssExtractPlugin时就不能使用style-loader了 14 { 15 loader: 'css-loader', 16 options: { 17 importLoaders: 2 //该方式可以让@import引入的css文件再次执行一边css打包loader 18 } 19 }, 20 ] 21 } 22 ] 23 }, 24 output: { 25 filename: '[name].js', 26 chunkFilename: '[name].js', 27 } 28}, base)

ok,此时我们就完成一个基本的打包es6,css的模块打包工具,为了支持更高的es6+语法,我们配置.babelrc文件,以及安装相应的npm包:

1npm install @babel/polyfill core-js -D

.babelrc文件如下:

1{ 2 "presets": [ 3 [ 4 "@babel/preset-env", // 将ES6语法转换为es5 5 { 6 "useBuiltIns": "usage", // 只编译需要编译的代码 7 "corejs": "3.0.1", 8 } 9 ], 10 ] 11}

我们会看到babelrc文件里面有"useBuiltIns": "usage", 这个配置涉及到一个关于webpack打包的高级用法,tree-shaking。

tree-shaking:用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于 ES2015 模块语法的 静态结构 特性,例如 import 和 export。这个术语和概念实际上是由 ES2015 模块打包工具 rollup 普及起来的。

我们通过使用tree-shaking,可以极大的减少代码的体积,对于提高打包性能很有帮助。为了使tree-shaking能生效,我们还要在webpack配置文件中开启:

1// webpack.base.js 2optimization: { 3 usedExports: true 4 }

还有一个问题,由于tree-shaking是基于import 和export的,当我们用import引入css文件时,是没有导出的,所以我们需要配置忽略css文件的tree-shaking,在package.json中添加如下配置:

1// package.json 2"sideEffects": [ 3 "*.css", 4 "*.less" 5 ],

在打包的过程中,每次执行打包都会新建一个打包文件,我们想要每次打包之前都清除上一次打包的文件怎么办呢?我们可以使用clean-webpack-plugin来实现,首先先安装,然后具体配置如下:

1// webpack.prod.js 2plugins: [ 3 new CleanWebpackPlugin() 4 ],

该插件会默认清除dist目录下的打包文件。 接下来我们安装jquery:

1npm install jquery -S

在index.js引入并使用:

1import $ from 'jquery'; 2import './styles/app.css' 3 4console.log($('#root').html('hello world'));

执行npm run build后,我们在浏览器中打开,即可看到jq的作用: image.png 但是我们看dist目录下的js文件,发现jquery和业务代码都打包进一个页面了,这样会导致当业务复杂时,整个页面代码会非常大,我们进一步做优化,即js代码分割。 根据webpack官网的方案,我们只需要进行简单的配置,便可以进行对js代码分割:

1//webpack.base.js 2optimization: { 3 splitChunks: { 4 chunks: 'all', 5 // chunks: 'async', // async表示只对异步代码进行分割 6 minSize: 30000, // 当超过指定大小时做代码分割 7 // maxSize: 200000, // 当大于最大尺寸时对代码进行二次分割 8 minChunks: 1, 9 maxAsyncRequests: 5, 10 maxInitialRequests: 3, 11 automaticNameDelimiter: '_', 12 name: true, 13 cacheGroups: { // 缓存组:如果满足vendor的条件,就按vender打包,否则按default打包 14 vendors: { 15 test: /[\\/]node_modules[\\/]/, 16 priority: -10, // 权重越大,打包优先级越高 17 // filename: 'js/vender.js' //将代码打包成名为vender.js的文件 18 name: 'vender' 19 }, 20 default: { 21 minChunks: 2, 22 priority: -20, 23 name: 'common', 24 // filename: 'js/common.js', 25 reuseExistingChunk: true // 是否复用已经打包过的代码 26 } 27 } 28 }, 29 usedExports: true 30 }

由于篇幅限制,splitChunks的具体配置我通过注释写出来了,如果想了解更详细的配置,后面大家可以去webpack官网查看。此时执行npm run build,我们可以看到代码已经进行了分割: image.png 当然只满足与css和js的打包还远远不够,我们项目中还会用到各种图片,字体图标,css预编译语言如less或者scss,由于这部分的安装比较简单,我们直接上代码。 首先安装相关依赖:

1npm install url-loader file-loader less less-loader

此时我们webpack.base.js中module变为:

1module: { 2 rules: [ 3 // 将es6编译成es5 4 { 5 test: /\.jsx?$/, // ?表示x有0个或一个 6 exclude: /node_modules/, // 不编译某个目录下的文件 7 include: path.resolve(__dirname, '../src'), // 只在include包含的目录下进行loader编译 8 use: [ 9 "babel-loader", 10 ] 11 }, 12 // 加载解析文件资源 13 { 14 test: /\.(jpg|png|gif)$/, 15 use: { 16 loader: 'url-loader', // 和file-loader功能相同,但更智能 17 options: { 18 // 配置打包后的文件名,具体可看webpack的file-loader文档 19 name: '[name].[ext]?[hash]', 20 outputPath: 'images/', 21 limit: 4096 // 当图片大小大于4k时将以文件形式输出,否则以base64输出 22 } 23 } 24 }, 25 // 引入字体,svg等文件 26 { 27 test: /\.(eot|ttf|svg)$/, 28 use: { 29 loader: 'file-loader' 30 } 31 } 32 ] 33 },

为了支持less,我们修改一下dev和prod文件:

1// webpack.dev.js 2module: { 3 rules: [ 4 { 5 test: /\.(css|less)$/, 6 use: [ // loader解析的顺序是从下到上,从右到左的顺序 7 'style-loader', //使用MiniCssExtractPlugin时就不能使用style-loader了 8 { 9 loader: 'css-loader', 10 options: { 11 importLoaders: 2 //该方式可以让@import引入的css文件再次执行一边css打包loader 12 } 13 }, 14 'less-loader', 15 ] 16 } 17 ] 18 } 19 20// webpack.prod.js 21module: { 22 rules: [ 23 { 24 test: /\.(css|less)$/, 25 use: [ // loader解析的顺序是从下到上,从右到左的顺序 26 { 27 loader: MiniCssExtractPlugin.loader, 28 options: { 29 filename: '[name].css', 30 chunkFilename: '[name].css', 31 publicPath: '../' //****最后打包的时候替换引入文件路径 32 }, 33 }, 34 { 35 loader: 'css-loader', 36 options: { 37 importLoaders: 2 //该方式可以让@import引入的css文件再次执行一边css打包loader 38 } 39 }, 40 'less-loader' 41 ] 42 } 43 ] 44 }

我们写一段less代码试试:

1body { 2 #root { 3 background-color: #000; 4 color: #fff; 5 } 6}

我们执行build之后在浏览器打开看看效果: image.png ok,至此,我们第一步也是最重要的一步已经完成了,由于开发项目的时候不可能每次改动代码都构建一次,这样时间成本太大了,我们想要实时看到改变的内容,这个时候就要用webpack4.0提供的devServer了,它使得我们项目可以支持热更新和热模块替换,我们需要在开发环境下对其进行配置,具体如下: 首先安装开发服务器模块:

1npm install webpack-dev-server -D

接着配置dev文件:

1webpack.dev.js 2const base = require('./webpack.base'); 3const merge = require('webpack-merge'); 4const webpack = require('webpack'); 5 6module.exports = merge({ 7 mode: 'development', 8 module: { 9 rules: [ 10 { 11 test: /\.(css|less)$/, 12 use: [ // loader解析的顺序是从下到上,从右到左的顺序 13 'style-loader', //使用MiniCssExtractPlugin时就不能使用style-loader了 14 'vue-style-loader', 15 { 16 loader: 'css-loader', 17 options: { 18 importLoaders: 2 //该方式可以让@import引入的css文件再次执行一边css打包loader 19 } 20 }, 21 // 'sass-loader', 22 'less-loader', 23 'postcss-loader', 24 ] 25 } 26 ] 27 }, 28 // 服务器配置 29 devServer: { 30 port: '8081', 31 // 当使用 HTML5 History API 时,任意的 404 响应都可能需要被替代为 index.html 32 historyApiFallback: true, // 解决单页面路由问题, 33 contentBase: '../dist', 34 open: true, //自动打开浏览器 35 hot: true, // 开启热替换, css代码跟新不刷新页面 36 // hotOnly: true 开启后只有手动配置才能更新,即使hot为true也不刷新浏览器 37 proxy: { 38 index: '', // 将index设置为空,可以对根路径进行转发 39 'api/get': 'xxxx.com/api', // 第一种方式,直接代理到api路径 40 'api/vue': { // 第二种方式,在路径需要临时替换时使用 41 target: 'xxxx.com/api', 42 pathRewrite: { 43 'head': 'demo' //此时访问head路径将被代理到demo下 44 }, 45 secure: false, //对https请求的配置,false为支持https 46 changeOrigin: true //做代理分发时允许访问其他网站,突破网站限制,建议在开发环境使用 47 }, 48 49 } 50 }, 51 plugins: [ 52 new webpack.HotModuleReplacementPlugin() 53 ], 54 output: { 55 filename: '[name].js', 56 chunkFilename: '[name].js', 57 } 58}, base)

以上代码中,要使用热模块替换,我们需要用到webpack自己集成的插件webpack.HotModuleReplacementPlugin,在devServer中,我们还可以设置开发环境中的代理proxy,这已经是目前开发的默认模式了,代码中一些属性的用法和含义我都做了注释,如果大家有兴趣,可以查看webpack原版官方文档,那里有更详细的配置信息。 我们再来修改package.json,添加开发环境的运行指令:

1// 在script里面添加 2"start": "webpack-dev-server --config ./build/webpack.dev.js",

我们执行 npm start,此时会自动打开浏览器,运行我们的项目。

到此,我们基本的一个支持ES6+Less/css+JQuery的单页应用打包工具已经做好了,当然这只是基础,后面的多页应用,vue/react/typescript都是在这个基础上构建的,让我们拭目以待。

多页面应用:

我们开发多页面应用还是需要用到之前使用的html-webpack-plugin插件,此时我们需要定义多个入口:

1// webpack.base.js 2entry: { 3 main: './src/index.js', 4 about: './src/about.js' 5 } 6 7plugins: [ 8new HtmlWebpackPlugin( 9 { 10 template, 11 title: 'webpack打包但单应用', 12 chunks: ['vender', 'main'], 13 filename: 'index.html' 14 } 15 ), 16 new HtmlWebpackPlugin( 17 { 18 template, 19 title: '关于我们', 20 chunks: ['vender', 'about'], 21 filename: 'about.html' 22 } 23 ), 24]

template是我们定义的public下的html路径,title是我们要植入html模版中的titl标签中的内容,我们在index.html中这么使用:

1<!DOCTYPE html> 2<html lang="en"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title><%= htmlWebpackPlugin.options.title %></title> 8 <link rel="shortcut icon" href="./favicon.ico"> 9</head> 10<body> 11 <div id="root"></div> 12</body> 13</html>

        这样,webpack配置的title就可以动态的添加到html页面中了,这里我要说一下在new HtmlWebpackPlugin中我们添加了chunks数组,这个数组就是我们要打包进页面的js,main和about分别代表入口的名字,vender就是我们定义optimization时里面cacheGroups属性值中vendors中定义的name,当代码超过30000b时就会生成vender.js文件。         此时我们执行npm run build,打包结束后将会生成2个html页面,对应的文件依赖也会引入,在浏览器中打开,亲测有效~ image.png

这样,一个基本的多页面打包工具就开发完成了,不过还有几点优化:

  1. 代码压缩,
  2. 第三方模块懒编译,我们可以使用webpack提供的dll技术做优化
  3. pwa技术引入 下面分别是相关实现: 1.代码压缩,我们使用terser-webpack-plugin压缩js,用optimize-css-assets-webpack-plugin压缩css
1npm install terser-webpack-plugin optimize-css-assets-webpack-plugin -D

我们在webpack.prod.js中添加一下配置:

1// 导入模块 2// 压缩css 3const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); 4// 压缩js 5const TerserPlugin = require('terser-webpack-plugin'); 6 7// 配置module.exports,添加配置如下 8optimization: { 9 minimizer: [ 10 new TerserPlugin({ // 压缩js代码 11 cache: true, // 启用文件缓存 12 parallel: true, // 使用多进程并行执行任务来提高构建效率 13 sourceMap: true, // 将错误消息位置映射到模块 14 terserOptions: { 15 drop_console: true, // 打包时剔除所有console.log 16 drop_debugger: true // 打包时剔除所有debugger 17 } 18 }), 19 new OptimizeCSSAssetsPlugin({})] // 压缩css代码 20 },
  1. pwa:渐进式网络应用程序(progressive web application - PWA),是一种可以提供类似于native app(原生应用程序) 体验的 web app(网络应用程序)。首先我们安装依赖:
1npm install workbox-webpack-plugin --save-dev

在需要做pwa的页面里加入如下脚本启动:

1if ('serviceWorker' in navigator) { window.addEventListener('load', () => { 2 navigator.serviceWorker.register('/service-worker.js').then(registration => { 3 console.log('SW registered: ', registration); 4 }).catch(registrationError => { 5 console.log('SW registration failed: ', registrationError); 6 }); 7 }); 8 }
  1. dll文件优化打包速度 关于dll问题,我们可以在官网上查询具体的使用方法,这里就不具体说明了。

至此,我们关于开发基于ES6+JQuery+Less/Scss的单页/多页脚手架就告于段落了,下面我们来集成对react/vue/typescript的支持。

1.支持react

我们首先安装一个babel模块:

1npm install --save-dev @babel/preset-react

然后在.babelrc中加入如下配置:

1{ 2 "presets": [ 3 [ 4 "@babel/preset-react", 5 { 6 "pragma": "dom", // default pragma is React.createElement 7 "pragmaFrag": "DomFrag", // default is React.Fragment 8 "throwIfNamespace": false // defaults to true 9 } 10 ] 11 ] 12}

然后在index.js中写入一段react代码:

1import React, {Component} from 'react' 2import ReactDOM from 'react-dom' 3 4class App extends Component { 5 render() { 6 return <div>react frame content.</div> 7 } 8} 9 10ReactDOM.render(<App />, document.getElementById('root'));

打包后即可在浏览器中看到效果。

2.支持vue

首先先安装对应npm包:

1npm install -D vue-loader vue-template-compiler

之后在webpack的配置文件中写入如下代码:

1// webpack.base.js 2const VueLoaderPlugin = require('vue-loader/lib/plugin') 3 4module.exports = { 5 module: { 6 rules: [ 7 // ... other rules 8 { 9 test: /\.vue$/, 10 loader: 'vue-loader' 11 } 12 ] 13 }, 14 plugins: [ 15 // make sure to include the plugin! 16 new VueLoaderPlugin() 17 ] 18}

如果要想解析.vue文件中的style,我们需要使用vue-style-loader模块,安装之后将其添加到loder中即可。 接下来我们写个简单的vue试一下吧:

1<template> 2 <div class="example"> 3 {{ msg }} 4 <img src="~/images/logo.png" /> 5 <img :src="imgSrc" /> 6 </div> 7</template> 8 9<script> 10import Logo from 'images/logo.png'; 11import 'css/common.css'; 12 13export default { 14 data () { 15 return { 16 msg: 'Hello world!单独的', 17 imgSrc: Logo 18 } 19 } 20} 21</script> 22 23<style lang="less"> 24.example { 25 color: red; 26 img { 27 border: 2px solid #000; 28 } 29} 30</style>

运行dev在浏览器中即可看到效果。 值得注意的是vue文件中引入资源的问题,使用相对路径会有问题,这里我们可以使用~/images/logo.png的方式或者require的方式来引入图片。

3.支持typescript

这里我们使用awesome-typescript-loader来编译typescript文件,也是官方推荐的一个加载器:

1npm install awesome-typescript-loader --save-dev

然后我们在webpack的配置文件base中,在module的rules里加入如下代码:

1{ 2 test: /\.tsx?$/, 3 loader: 'awesome-typescript-loader' 4 }

最后一步,添加tsconfig.json文件:

1{ 2 "compilerOptions": { 3 "noImplicitAny": true, 4 "removeComments": true 5 }, 6 "awesomeTypescriptLoaderOptions": { 7 /* ... */ 8 } 9}

该文件有很多灵活的配置项,大家如果想了解更多可以去typescript官网上查看相关文档。 至此,所有的配置都完成了,是不是很累?哈哈,当然脚手架中还存在一些优化的地方,欢迎大家可以一起完善。

未完成的优化点:
  • vue文件内部style无法独立抽出样式,只能通过引入css文件的方式加载样式
  • 公用css文件问题:多页面打包时,如果都引入了同一个css,无法服用这个css,希望能将这个css文件作为一个公共模块单独引用.

更多推荐

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )