введение
В последнее время в проекте необходимо предоставить упакованный JS SDK.Хотя это очень простая функция в настоящее время, она все же выбрана для удобства обслуживания и расширения в будущем.webpackВ качестве инструмента упаковки, в качестве справки, порекомендуйте хорошую статью, заинтересованные друзья могут сначала прочитать ее.
JavaScript SDK Design Guide(китайский перевод:Рекомендации по разработке JavaScript SDK)
Цель
В качестве SDK я хочу достичь следующей цели
- предоставить схему загрузки
- Воздействие общей переменной, лучше поддерживать различные нагрузки
- Доступен в несжатой и сжатой версиях
- Индивидуальные версии доступны для разных партнеров
- На внутреннюю реализацию ссылаются модули, что удобно для расширения
Далее пошагово как пройтиwebpackвыполнить
Подготовить
Если нам, наконец, нужно предоставить SDK следующим образом
// 引用
<script type="text/javascript" src="http://xxx.com/sdk.js"></script>
// 使用
window.SDK.Shop.getList() // 获取门店信息列表
window.SDK.Store.getById() // 通过ID获取商品信息
Тогда список файлов должен быть примерно следующим.
|
| - package.json
| - webpack.config.js
| - node_modules
| - src
| - index.js
| - lib
| - shop.js
| - store.js
| - dist
| - build.js
webpackпройти черезindex.jsИмпортируйте упакованные файлы и поместите их вdistпапку, код некоторых ключевых файлов должен быть следующим
webpack.config.js
let path = require('path')
let webpack = require('webpack')
module.exports = {
entry: {
'sdk': ['./src/index.js']
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
// 压缩混淆 js
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
})
]
}
shop.js
module.exports = {
getList: function () {
.....
}
}
store.js
module.exports = {
getById: function (id) {
.....
}
}
index.js
var Shop = require('./lib/shop.js')
var Store = require('./lib/store.js')
module.exports = {
Shop: Shop,
Store: Store
}
build.js
// 这里简单的 copy 了 vue-cli 提供的 build 代码
let webpackConfig = require('./webpack.config')
let rm = require('rimraf')
let path = require('path')
let webpack = require('webpack')
let util = require('util')
const compileCallback = (er, stats) => {
if (er) throw er
stats = util.isArray(stats.stats) ? stats.stats : [stats]
stats.forEach((item) => {
process.stdout.write(item.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n\n')
})
console.log('Build complete.\n')
}
rm(path.resolve(__dirname, './dist'), err => {
if (err) throw err
let compiler = webpack(webpackConfig)
compiler.run(compileCallback)
})
строить планы
1. Загрузить ссылки
Эта часть хорошо реализована
- Укажите статический адрес файла (или адрес CDN) для простой загрузки через html
Предоставьте пакет npm и загрузите его на стороне сервера (поскольку на данный момент такого требования нет, поэтому сначала зависните)
2. Откройте общедоступную переменную
Самый простой способ сделать это -index.jsРигаwindow.SDK = ...
ноwebpackЕсть лучшие решенияoutput.library
output
параметры в основном используются для настройки правил вывода файла, в то время какoutput.library
Этот параметр можно использовать для предоставления файла в качестве переменной, когда вывод должен быть элементом конфигурации для упаковки файла SDK.
Вот еще одинwebpackучебник, чтобы помочь вам, как использовать
library
Создать библиотеку
другой вариантoutput.libraryTarget
Вы можете настроить, как выводить переменные, значение по умолчаниюvar
Кратко объясните значение этих значений
- var: экспортировать переменную в текущей области
- assign: экспортировать переменную как глобальную переменную
- это: экспортируется как
this
атрибут этогоthis
Не обязательноwindow
, в зависимости от того, где находится ссылка на SDK- окно: экспортировать как
window
Атрибут, по сути, даже глобальная переменная- глобальный: экспортировать как
global
Атрибут , по оценкам, это имя переменной используется чаще. .- commonjs: экспортировать как
exports
Атрибут экспортируемого формата можно найти вCommonJSупоминается в среде- commonjs2: назначить
module.exports
, также может быть использован вCommonJSокружающая обстановка- amd: подвергается воздействиюAMDмодуль
- umd: представлен как формат, доступный для всех модулей
- JSONP: пакет кjsonpупаковочная тара, то естьFunction
Итак, давайте немного изменим егоwebpack.config.jsкод
module.exports = {
...
output: {
path: './dist',
filename: '[name].js',
library: 'SDK',
libraryTarget: "umd"
}
...
}
3. Доступен в двух версиях
Просто напишите дваbuildскрипты, упакованные как сжатый и несжатый код соответственно, ноwebpackЕго также можно экспортировать как несколько конфигураций (это также обнаруживаетwebpackкак умножитьoutput
настроить разные параметры)
Итак, нашwebpack.config.jsКод изменен на
module.exports = [
// 未压缩版
{
entry: {
'sdk': './src/index.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
library: 'SDK',
libraryTarget: "umd"
}
},
// 压缩版
{
entry: {
'sdk.min': './src/index.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
library: 'SDK',
libraryTarget: "umd"
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
})
]
}
]
Результат после упаковки показан на следующем рисунке
4. Обеспечить индивидуальную версию
Это относительно просто, вы можете сделать несколько конфигураций так же, как предыдущую, или вы можете простоentry
написать несколько записей в
webpack.config.jsКод изменен на
module.exports = [
{
entry: {
'sdk': './src/index.js',
'custom': './src/custom.js'
}
...
},
...
]
5. Внутренняя реализация через ссылку на модуль
Это уже не многословно... После ряда настроек, не говоря уже о модулях, ES6 может быть добавлен для вас, но следует отметить, что если вы внедритеbabelИли другие библиотеки, упакованныеSDKФайл очень большой, даже простая ссылка наwebpack-mergeувеличит ёмкость на 50К, так что лучше писать родным способом, если надоajax
Просто инкапсулируйте другие функции и по возможности не ссылайтесь на другие библиотеки.Если вы считаете, что размер файла слишком велик, вы можете использоватьwebpack-bundle-analyzerАнализировать распределение размеров файлов и наличие повторяющихся ссылок
Эпилог
Несмотря на то, что это небольшой проект, его следует рассматривать комплексно на начальном этапе.Хотя текущий проект небольшой, неясно, во что он вырастет в будущем.Некоторые люди могут сказать, что такой простой проект должен быть инкапсулирован с замыкание и выставили два интерфейса.,зачем так усложнять,но если потом нужно добавить новые интерфейсы,если нужно предоставить два sdks,каждый с разными интерфейсами,и некоторые одинаковые интерфейсы,если рефакторить в это время , будет ли это правильно?Онлайн имеет большое влияние? Сколько тестов требуется? Это незаметно добавляет нам много затрат и неопределенности.
Я надеюсь, что эта относительно простая статья поможет вам в создании проекта SDK~