執行命令npm init
建立 package.json 文件,一步步輸入你本身的組件基本信息,下面是我建立的css
{ "name": "react-code-previewer", "version": "0.0.1", "description": "基於 react 和 antd 的代碼預覽器組件", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", "url": "git+ssh://git@github.com/zhangwei900808/react-code-previewer.git" }, "keywords": [ "react", "antd", "code-preview" ], "author": "zhangwei", "license": "MIT", "bugs": { "url": "https://github.com/zhangwei900808/react-code-previewer/issues" }, "homepage": "https://github.com/zhangwei900808/react-code-previewer#readme" }
首先在項目目錄下建立相應文件夾和基本配置文件,目錄結構以下所示:html
|-- com.github |-- .editorconfig |-- .gitignore |-- .npmignore |-- LICENSE |-- package.json |-- .react-code-previewer |-- components | |-- index.js | |-- code-previewer | |-- index.js | |-- style | |-- index.js | |-- index.scss |-- src
建立好以後,咱們開始製做該組件,在目錄 code-previewer/index.js 添加代碼,以下所示:前端
import React, { Component } from "react"; class CodePreviewer extends Component { render() { return ( <div className="code-preview-container"> <div className="cp-component"> <div className="component-header">header</div> <div className="component-content">content</div> <div className="component-footer">footer</div> </div> <div className="cp-code"> <div className="code-header">code header</div> <div className="code-tabs">code tabs</div> <div className="code-content">code content</div> </div> </div> ); } } export default CodePreviewer;
在目錄 code-previewer/style/index.js 添加代碼,以下所示:node
import "./index.scss";
在目錄 code-previewer/style/index.scss 添加代碼,以下所示:react
.code-preview-container { .cp-component { .component-header { color: red; } .component-content { color: green; } .component-footer { color: yellow; } } .cp-code { .code-header { color: red; } .code-tabs { color: green; } .code-content { color: yellow; } } }
咱們如今已經初始化組件內容,雖然很簡單,後面咱們再優化,如今咱們要對外暴露該組件,因此咱們在目錄 /components/index.js 添加代碼,以下:webpack
import CodePreview from "./code-previewer"; export { CodePreview }; export default { CodePreview };
首先咱們在目錄建立.react-code-preview/webpack.config.umd.js 文件,並添加以下代碼:git
const fs = require("fs"); const path = require("path"); const webpack = require("webpack"); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); const nodeExternals = require("webpack-node-externals"); const WebpackMd5Hash = require("webpack-md5-hash"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const resolve = dir => path.join(__dirname, ".", dir); const isProd = process.env.NODE_ENV === "production"; const { version, name, description } = require("../package.json"); const distDir = path.join(process.cwd(), "dist"); module.exports = { mode: "production", entry: { [name]: "./components/index.js" }, output: { path: distDir, filename: "[name].min.js", // 採用通用模塊定義 libraryTarget: "umd", library: name }, devtool: "#source-map", module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: "babel-loader" } }, { test: /\.(sa|sc|c)ss$/, use: [ MiniCssExtractPlugin.loader, { loader: "css-loader", options: { sourceMap: true } }, { loader: "sass-loader", options: { sourceMap: true } } ] } ] }, resolve: { enforceExtension: false, extensions: [".js", ".jsx", ".json", ".less", ".css"] }, // 注意:本地預覽的時候要註釋,不然報 require undefined // https://stackoverflow.com/questions/45818937/webpack-uncaught-referenceerror-require-is-not-defined externals: [nodeExternals()], plugins: [ new CleanWebpackPlugin({ cleanOnceBeforeBuildPatterns: [distDir] }), new MiniCssExtractPlugin({ filename: "[name].css" }), new WebpackMd5Hash(), new webpack.BannerPlugin(` \n ${name} v${version} \n ${description} ${fs.readFileSync(path.join(process.cwd(), "LICENSE"))}`) ], //壓縮js optimization: { splitChunks: { cacheGroups: { styles: { name: "styles", test: /\.scss$/, chunks: "all", enforce: true } } }, minimizer: [ new UglifyJsPlugin({ cache: true, parallel: true, sourceMap: true }), new OptimizeCssAssetsPlugin({ assetNameRegExp: /\.css\.*(?!.*map)/g, //注意不要寫成 /\.css$/g cssProcessor: require("cssnano"), cssProcessorOptions: { discardComments: { removeAll: true }, safe: true, autoprefixer: false }, canPrint: true }) ] }, node: { setImmediate: false, dgram: "empty", fs: "empty", net: "empty", tls: "empty", child_process: "empty" } };
在目錄根目錄下建立 .babelrc 文件,並添加以下代碼:github
{ "presets": [ ["@babel/preset-env", { "modules": false, }], "@babel/preset-react" ], "plugins": [ ["@babel/plugin-transform-runtime", { "useESModules": false }] ] }
建立完成以後添加依賴包,並修改 package.json 文件,以下:web
"scripts": { "build:umd": "webpack --mode production --config .react-code-previewer/webpack.config.umd.js" }, "devDependencies": { "@babel/cli": "^7.5.5", "@babel/core": "^7.5.5", "@babel/plugin-transform-runtime": "^7.5.5", "@babel/preset-env": "^7.5.5", "@babel/preset-react": "^7.0.0", "@babel/runtime": "^7.5.5", "babel-loader": "^8.0.6", "clean-webpack-plugin": "^3.0.0", "css-loader": "^3.2.0", "fs": "^0.0.1-security", "mini-css-extract-plugin": "^0.8.0", "optimize-css-assets-webpack-plugin": "^5.0.3", "path": "^0.12.7", "react": "^16.9.0", "sass-loader": "^7.2.0", "style-loader": "^1.0.0", "uglifyjs-webpack-plugin": "^2.2.0", "webpack": "^4.39.2", "webpack-cli": "^3.3.6", "webpack-node-externals": "^1.7.2" }
添加完成以後,執行命令打包npm
yarn build:umd
成功在 dist 目錄下建立好了打包後的.js文件,目錄以下所示:
|-- com.github |-- .babelrc |-- .editorconfig |-- .gitignore |-- .npmignore |-- LICENSE |-- directoryList.md |-- package.json |-- yarn.lock |-- .react-code-previewer | |-- webpack.config.umd.js |-- components | |-- index.js | |-- code-previewer | |-- index.js | |-- style | |-- index.js | |-- index.scss |-- dist | |-- react-code-previewer.min.js | |-- react-code-previewer.min.js.map |-- src
注意:由於後面組件會使用 bable-plugins-import 按需加載組件,因此上面的組件並無直接引用.scss文件,這樣也就不會在 dist 文件夾下打包.css文件了,可是.css 文件必定要有,後面會講gulp如何打包.css文件
上面講了如何使用webpack.config.umd.js 的 umd 模式打包 react 組件,接下來咱們講如何使用 commonjs 模式打包 react 組件,commonjs 模式打包咱們使用的是 babel 直接打包,而且要修改.babelrc 和 package.json,以下:
.babelrc
{ "presets": [ ["@babel/env", { "loose": true, "modules": "cjs" }], "@babel/preset-react" ], "plugins": [ ["@babel/plugin-transform-runtime", { "useESModules": false }], ] }
package.json
"build:commonjs": "babel components -d lib --source-maps"
添加完成以後,執行命令打包
yarn build:commonjs
|-- com.github |-- .babelrc |-- .editorconfig |-- .gitignore |-- .npmignore |-- LICENSE |-- directoryList.md |-- package.json |-- yarn.lock |-- .react-code-previewer | |-- webpack.config.umd.js |-- components | |-- index.js | |-- code-previewer | |-- index.js | |-- style | |-- index.js | |-- index.scss |-- dist | |-- react-code-previewer.min.js | |-- react-code-previewer.min.js.map |-- lib | |-- index.js | |-- index.js.map | |-- code-previewer | |-- index.js | |-- index.js.map | |-- style | |-- index.js | |-- index.js.map |-- src
es modules打包和 babel 打包很相似也是經過 babel 打包,不一樣的是.babelrc 文件有所修改,代碼以下:
.babelrc
{ "presets": [ ["@babel/env", { "loose": true, "modules": false }], "@babel/preset-react" ], "plugins": [ ["@babel/plugin-transform-runtime", { "useESModules": true }] ] }
package.json
"build:es": "babel components -d es --source-maps"
添加完成以後,執行下面命令打包
yarn build:es
|-- react-code-previewer |-- .babelrc |-- .editorconfig |-- .gitignore |-- .npmignore |-- LICENSE |-- package.json |-- yarn.lock |-- .react-code-previewer | |-- webpack.config.umd.js |-- components | |-- index.js | |-- code-previewer | |-- index.js | |-- style | |-- index.js | |-- index.scss |-- dist | |-- react-code-previewer.min.js | |-- react-code-previewer.min.js.map |-- es | |-- index.js | |-- index.js.map | |-- code-previewer | |-- index.js | |-- index.js.map | |-- style | |-- index.js | |-- index.js.map |-- lib | |-- index.js | |-- index.js.map | |-- code-previewer | |-- index.js | |-- index.js.map | |-- style | |-- index.js | |-- index.js.map |-- src
這樣就完成了 umd、commonjs 和 es 的三種打包方式,可是這樣有個問題:每次打包都要修改.babelrc 文件,能不能直接經過一條命令打包三種模式的方法呢?下面咱們就來說講。
經過三種打包模式咱們發現,.babelrc 文件跟三種模式打包有關,尤爲是其中幾個對象的設置,如:loose、modules 和 useESModules,其它的設置都同樣,因此咱們可使用cross-env BABEL_ENV=umd(commonjs 或者 es)增長 BABEL_ENV 環境變量進行判斷。還有,.babelrc 文件咱們要換成.babelrc.js,由於前者不能使用 js 語法,這裏有篇文章很好的分析.babelrc、.babelrc.js 和 babel.config.js文件之間的區別。代碼以下:
.babelrc.js
let babel_env = process.env["BABEL_ENV"]; let loose = false, modules = false, useESModules = false; switch (babel_env) { case "commonjs": loose = true; modules = "cjs"; useESModules = false; break; case "es": loose = true; modules = false; useESModules = true; break; case "umd": loose = false; modules = false; useESModules = false; break; } const presets = [["@babel/preset-env", { loose, modules }], "@babel/preset-react"]; const plugins = ["@babel/plugin-proposal-object-rest-spread", ["@babel/plugin-transform-runtime", { useESModules }]]; module.exports = { presets, plugins };
另外要注意的一點是,每次打包最好把以前的 dist、lib、es 目錄刪除防止相互干擾,刪除目錄咱們使用 rimraf 包,以下:
package.json
"build:umd": "cross-env BABEL_ENV=umd webpack --mode production --config .react-code-previewer/webpack.config.umd.js", "build:commonjs": "rimraf lib && cross-env BABEL_ENV=commonjs babel components -d lib --source-maps", "build:es": "rimraf es && cross-env BABEL_ENV=es babel components -d es --source-maps"
注意:由於 umd 是經過 webpack.config.umd.js 打包的因此咱們直接在該文件中刪除 dist 文件夾
plugins: [ new CleanWebpackPlugin({ cleanOnceBeforeBuildPatterns: [path.join(process.cwd(), "dist")] }) ]
設置好以後,咱們分別打包一下,以下所示:
三種打包模式都成功打包成 dist、es 和 lib 文件夾中,雖然都成功了可是每次執行三條命令很是麻煩,如何經過一條命令打包三種模式呢,其實也很簡單,代碼以下:
package.json
"scripts": { "build:all": "yarn build:umd && yarn build:commonjs && yarn build:es" },
這樣咱們只要執行 yarn build:all
命令三種模式下的打包都能完成,很是方便。
好了,到了這裏心急的小夥伴必定要說,你把 js都打包好了,那 css呢?如今咱們就來處理 css 打包,首先咱們建立 gulpfile.js文件,代碼以下:
const fs = require("fs"); const gulp = require("gulp"); const path = require("path"); const cleanCSS = require("gulp-clean-css"); const rename = require("gulp-rename"); const concat = require("gulp-concat"); const replace = require("gulp-replace"); const sass = require("gulp-sass"); const sourcemaps = require("gulp-sourcemaps"); const autoprefixer = require("gulp-autoprefixer"); const size = require("gulp-filesize"); const { name } = require("../package.json"); const resolve = dir => path.join(__dirname, ".", dir); const distDir = resolve("../dist"); const libDir = resolve("../lib"); const esDir = resolve("../es"); const sassDir = resolve("../components/**/*.scss"); const indexJsDir = resolve("../components/**/style/index.js"); // 複製 sass 文件到 lib es 文件夾下 gulp.task("copy-sass", () => { return gulp .src(sassDir) .pipe(sourcemaps.init()) .pipe(sourcemaps.write(".")) .pipe(gulp.dest(libDir)) .pipe(gulp.dest(esDir)); }); // 根據 index.js 建立一個全新的 css.js 供按需加載 styel:'css' 使用 gulp.task("replace-indexjs", () => { return gulp .src(indexJsDir) .pipe(sourcemaps.init()) .pipe(replace("scss", "css")) .pipe( rename(function(path) { path.basename = "css"; path.extname = ".js"; }) ) .pipe(sourcemaps.write(".")) .pipe(gulp.dest(libDir)) .pipe(gulp.dest(esDir)); }); // 編譯 sass 文件到 es 和 lib 文件夾下 gulp.task("compile-sass", () => { return gulp .src(sassDir) .pipe(sourcemaps.init()) .pipe(sass()) .pipe(autoprefixer()) .pipe(cleanCSS()) .pipe(sourcemaps.write(".")) .pipe(gulp.dest(libDir)) .pipe(gulp.dest(esDir)); }); // 編譯 sass 到 dist 文件夾下 gulp.task("dist-css", () => { return gulp .src(sassDir) .pipe(sourcemaps.init()) .pipe(sass()) .pipe(autoprefixer()) .pipe(concat(`${name}.css`)) .pipe(size()) .pipe(sourcemaps.write(".")) .pipe(gulp.dest(distDir)) .pipe(concat(`${name}.min.css`)) .pipe(size()) .pipe(cleanCSS()) .pipe(sourcemaps.write(".")) .pipe(gulp.dest(distDir)); }); gulp.task("compile", gulp.series(gulp.parallel("copy-sass", "replace-indexjs", "compile-sass", "dist-css")));
package.json
"scripts": { "build:css": "cd .react-code-previewer && gulp compile", "build:umd": "cross-env BABEL_ENV=umd webpack --mode production --config .react-code-previewer/webpack.config.umd.js", "build:commonjs": "rimraf lib && cross-env BABEL_ENV=commonjs babel components -d lib --source-maps", "build:es": "rimraf es && cross-env BABEL_ENV=es babel components -d es --source-maps", "build:all": "yarn build:umd && yarn build:commonjs && yarn build:es" }, "devDependencies": { "@babel/cli": "^7.5.5", "@babel/core": "^7.5.5", "@babel/plugin-transform-runtime": "^7.5.5", "@babel/preset-env": "^7.5.5", "@babel/preset-react": "^7.0.0", "@babel/runtime": "^7.5.5", "babel-loader": "^8.0.6", "clean-webpack-plugin": "^3.0.0", "cross-env": "^5.2.0", "css-loader": "^3.2.0", "fs": "^0.0.1-security", "gulp": "^4.0.2", "gulp-autoprefixer": "^6.1.0", "gulp-clean-css": "^4.2.0", "gulp-concat": "^2.6.1", "gulp-filesize": "^0.0.6", "gulp-rename": "^1.4.0", "gulp-replace": "^1.0.0", "gulp-sass": "^4.0.2", "gulp-sourcemaps": "^2.6.5", "mini-css-extract-plugin": "^0.8.0", "optimize-css-assets-webpack-plugin": "^5.0.3", "path": "^0.12.7", "react": "^16.9.0", "sass-loader": "^7.2.0", "style-loader": "^1.0.0", "uglifyjs-webpack-plugin": "^2.2.0", "webpack": "^4.39.2", "webpack-cli": "^3.3.6", "webpack-node-externals": "^1.7.2" }
修改好了咱們執行命令打包 css:
yarn build:css
這樣咱們就完成了 js 的三種模式和 css 的打包,不要忘了把 build:css也放到 build:all 命令裏面,以下:
"build:all": "yarn build:umd && yarn build:commonjs && yarn build:es && yarn build:css"
接下來咱們會提交到 github以及發佈到 npm。
咱們在 github上面建立一個新項目:react-code-previewer,而後在本地代碼執行 以下 git 命令:
git init git remote add origin git@github.com:zhangwei900808/react-code-previewer.git git add . git commit -am 'your-commit-msg' git push -u origin master
完成了組件製做以後咱們就能夠發佈到 npm 其餘人也就能夠直接經過 npm install 你的插件了。
npm login
npm version your-package-version
npm publish
注意:發佈到 npm 的時候 npm 源要設置成官方的
npm set registry http://registry.npmjs.org
在你的另外的 react項目中咱們添加剛上傳的包:
yarn add react-code-previewer
import { CodePreviewer } from "react-code-previewer";
.babelrc
{ "presets": ["@babel/preset-env", "@babel/preset-react"], "plugins": [ [ "import", { "libraryName": "react-code-previewer", "libraryDirectory": "lib", "style": "css" } ] ] }
按需加載咱們使用的是 antd 提供的babel-plugin-import插件,這裏要注意的是 style 屬性:
style: true 表示從style/index.scss 加載樣式
style: 'css' 表示從 style/index.css 加載樣式
上面雖然寫了一個react-code-previewer組件,可是裏面沒內容,主要是演示三種模式下打包和 css 打包,好了,如今咱們來完善下這個組件,併發布到 github pages預覽效果。
代碼都完成以後,咱們要在本地看看效果,首先添加webpack.config.dev.js文件,須要注意的是.dev.js和.umd.js文件相差不大.dev.js文件少了output多了HtmlWebpackPlugin配置,代碼以下:
const fs = require("fs"); const path = require("path"); const webpack = require("webpack"); const TerserPlugin = require("terser-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); const nodeExternals = require("webpack-node-externals"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const postcssPresetEnv = require("postcss-preset-env"); const resolve = dir => path.join(__dirname, ".", dir); const isProd = process.env.NODE_ENV === "production"; const { version, name, description } = require("../package.json"); const docsDir = path.join(process.cwd(), "docs"); module.exports = { mode: "development", entry: { [name]: "./src/index.js" }, // output: { // // path: resolve("dist"), // 輸出目錄 // path: docsDir, // filename: "static/js/[name].min.js", // chunkFilename: "static/js/[name].chunk.js", // umdNamedDefine: true, // 是否將模塊名稱做爲 AMD 輸出的命名空間 // //不加下面幾行,被引用會被報錯 // libraryTarget: "umd", // 採用通用模塊定義 // library: [name] // }, devtool: "#source-map", module: { rules: [ { test: /\.md$/, use: "raw-loader" }, { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: "babel-loader" } }, { test: /\.(pc|sc|c)ss$/, use: [ // fallback to style-loader in development { loader: "style-loader" }, { loader: "css-loader", options: { sourceMap: true, importLoaders: 1 } }, { loader: "postcss-loader", options: { ident: "postcss", sourceMap: true, plugins: () => [ postcssPresetEnv({ stage: 3, features: { "custom-properties": true, "nesting-rules": true }, browsers: "last 2 versions" }) ] } } ] }, { test: /\.(jpe?g|png|gif|ogg|mp3)$/, use: [ { loader: "url-loader", options: { limit: 10 * 1000 } } ] }, { test: /\.(woff|svg|eot|ttf)\??.*$/, use: ["file-loader"] } ] }, resolve: { enforceExtension: false, extensions: [".js", ".jsx", ".json", ".less", ".css"] }, plugins: [ new MiniCssExtractPlugin({ filename: "static/css/[name].min.css", chunkFilename: "static/css/[name].chunk.css" }), //預覽 new HtmlWebpackPlugin({ template: path.join(__dirname, "../public/index.html"), //指定要打包的html路徑和文件名 filename: "./index.html" //指定輸出路徑和文件名 }), new webpack.HotModuleReplacementPlugin(), new webpack.NamedModulesPlugin(), new webpack.NoEmitOnErrorsPlugin() ], //壓縮js optimization: { minimizer: [ new TerserPlugin({ cache: true, parallel: true, sourceMap: true }), new OptimizeCssAssetsPlugin({ assetNameRegExp: /\.css\.*(?!.*map)/g, //注意不要寫成 /\.css$/g cssProcessor: require("cssnano"), cssProcessorOptions: { discardComments: { removeAll: true }, safe: true, autoprefixer: false }, canPrint: true }) ] } };
如今咱們修改下.babelrc.js使其可以支持ant-design
// 預覽狀況下添加對 antd 按需加載樣式的支持 if (babel_env === "preview") { plugins.push([ "import", { libraryName: "antd", libraryDirectory: "es", style: "css" // `style: true` 會加載 less 文件 }, "ant-design" ]); }
這樣咱們再修改下package.json就能夠本地預覽了,代碼以下:
"start": "cross-env BABEL_ENV=preview webpack-dev-server --port 3002 --open --config scripts/webpack.config.dev.js",
執行命令yarn start
便可預覽
一、安裝gh-pages
yarn add gh-pages
二、添加webpack.config.prod.js文件,.prod.js比.umd.js文件多了個HtmlWebpackPlugin的配置其餘的沒有太大變化,代碼以下:
const path = require("path"); const webpack = require("webpack"); const TerserPlugin = require("terser-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); const nodeExternals = require("webpack-node-externals"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const InlineManifestWebpackPlugin = require("inline-manifest-webpack-plugin"); const HtmlWebpackInlineSourcePlugin = require("html-webpack-inline-source-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); const { version, name, description } = require("../package.json"); const postcssPresetEnv = require("postcss-preset-env"); const resolve = dir => path.join(__dirname, ".", dir); const isProd = process.env.NODE_ENV === "production"; const docsDir = path.join(process.cwd(), "docs"); module.exports = { mode: "production", // 預覽 entry: { main: "./src/index.js" }, output: { // path: resolve("dist"), // 輸出目錄 path: docsDir, filename: "static/js/[name].min.js", chunkFilename: "static/js/[name].chunk.js", umdNamedDefine: true, // 是否將模塊名稱做爲 AMD 輸出的命名空間 //不加下面幾行,被引用會被報錯 libraryTarget: "umd", // 採用通用模塊定義 library: [name] }, devtool: "#source-map", module: { rules: [ { test: /\.md$/, use: "raw-loader" }, { test: /\.(pc|le|sc|c)ss$/, use: [ MiniCssExtractPlugin.loader, { loader: "css-loader", options: { importLoaders: 1, sourceMap: true } }, { loader: "postcss-loader", options: { ident: "postcss", sourceMap: true, plugins: () => [ postcssPresetEnv({ stage: 3, features: { "custom-properties": true, "nesting-rules": true }, browsers: "last 2 versions" }) ] } } ] }, { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: "babel-loader" } }, { test: /\.(jpe?g|png|gif|ogg|mp3)$/, use: [ { loader: "url-loader", options: { limit: 10 * 1000 } } ] } ] }, resolve: { extensions: [".js", ".jsx"] }, plugins: [ new CleanWebpackPlugin({ cleanOnceBeforeBuildPatterns: [docsDir] }), new MiniCssExtractPlugin({ filename: "static/css/[name].min.css", chunkFilename: "static/css/[name].chunk.css" }), //預覽 new HtmlWebpackPlugin({ //指定要打包的html路徑和文件名 template: path.join(__dirname, "../public/index.html"), //指定輸出路徑和文件名 filename: "./index.html" }), new InlineManifestWebpackPlugin(), new HtmlWebpackInlineSourcePlugin(), new webpack.HotModuleReplacementPlugin(), new webpack.NamedModulesPlugin(), new webpack.NoEmitOnErrorsPlugin() ], //壓縮js optimization: { splitChunks: { cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, name: "vendors", minSize: 30000, minChunks: 1, chunks: "initial", priority: 1 // 該配置項是設置處理的優先級,數值越大越優先處理 }, commons: { test: /[\\/]src[\\/]common[\\/]/, name: "commons", minSize: 30000, minChunks: 3, chunks: "initial", priority: -1, reuseExistingChunk: true // 這個配置容許咱們使用已經存在的代碼塊 } } }, // 生成運行時.js 文件,並寫入到.html runtimeChunk: "single", minimizer: [ new TerserPlugin({ cache: true, parallel: true, sourceMap: true }), new OptimizeCssAssetsPlugin({ assetNameRegExp: /\.css\.*(?!.*map)/g, //注意不要寫成 /\.css$/g cssProcessor: require("cssnano"), cssProcessorOptions: { //生成.css.map 文件 map: true, discardComments: { removeAll: true }, // 避免 cssnano 從新計算 z-index safe: true, // 關閉autoprefixer功能 // 使用postcss cssnano的autoprefixer功能 autoprefixer: false }, canPrint: true }) ] } };
二、配置package.json
"build:prod": "cross-env BABEL_ENV=preview webpack --mode production --config scripts/webpack.config.prod.js", "deploy:docs": "yarn build:prod && gh-pages -d docs"
執行yarn deploy:docs
便可編譯預覽代碼到build文件夾,而後gh-pages建立gh-pages分支到github,而後咱們到github設置gh-pages爲github pages便可,這樣就完成了在線預覽了。
一、三種打包方式的不一樣umd、commonjs和es modules,所修改的webpack文件和對應的bable.js文件的區別,理解和總結以後之後能夠用相同的方法打造本身的組件庫。
二、js sourcemap使用--source-maps
生成,css sourcemap使用生成
const sourcemaps = require("gulp-sourcemaps"); ... .pipe(sourcemaps.init()) .pipe(sourcemaps.write(".")) ...
三、gulp能夠對png的打包支持
const imgDir = resolve("../components/**/*.png"); // 複製 img 文件到 lib es 文件夾下 gulp.task("copy-img", () => { return gulp .src(imgDir) .pipe(gulp.dest(libDir)) .pipe(gulp.dest(esDir)); });
四、webpack4和babel7跟以前版本有所區別,如webpack4有optimization屬性,babel7使用的包是@babel開頭等等
五、若是你想使用本身的域名,那麼你要在public裏面添加 CNAME 文件,而後添加yarn add copy-webpack-plugin
插件,再修改plugins屬性new CopyPlugin([{ from: "./public/CNAME", to: "." }])
便可,做用就是把CNAME文件從public打包到build文件夾下,這樣發佈到github pages以後就會被其識別就能夠訪問了。
六、404
七、github pages history模式
react-code-previewer
hiynn-design
JavaScript模塊化CommonJS/AMD/CMD/UMD/ES6Module的區別
前端構建工具發展及其比較
cuke-ui
ant-landing)
黃瓜 UI: 一個即插即用的 React 組件庫
webpack4 SplitChunks實現代碼分隔詳解
Show me the code,babel 7 最佳實踐!
使用模塊化工具打包本身開發的JS庫(webpack/rollup)對比總結
gulp實戰(2) - 自動化打包CSS文件(完整版)
打包平臺Webpack(V3-V4)和Babel(V6-V7)升級~
[babel.config.js、.babelrc、.babelrc.js 區別