{"id":22695496,"url":"https://github.com/pressbooks/pressbooks-build-tools","last_synced_at":"2026-03-05T02:13:21.467Z","repository":{"id":27281680,"uuid":"113193159","full_name":"pressbooks/pressbooks-build-tools","owner":"pressbooks","description":"NPM package which includes all asset linting and build tools for Pressbooks projects.","archived":false,"fork":false,"pushed_at":"2026-03-05T00:38:37.000Z","size":1183,"stargazers_count":2,"open_issues_count":7,"forks_count":1,"subscribers_count":7,"default_branch":"dev","last_synced_at":"2026-03-05T00:56:04.540Z","etag":null,"topics":["assets","eslint","laravel-mix","npm","prettier","stylelint","webpack"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pressbooks.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-12-05T14:35:16.000Z","updated_at":"2026-03-04T18:55:06.000Z","dependencies_parsed_at":"2023-02-10T11:01:03.803Z","dependency_job_id":"c7290da8-f250-4714-9374-b5721611a965","html_url":"https://github.com/pressbooks/pressbooks-build-tools","commit_stats":{"total_commits":338,"total_committers":9,"mean_commits":37.55555555555556,"dds":"0.24852071005917165","last_synced_commit":"5060240b5685ce7227fd664e48d2a03759c22088"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"purl":"pkg:github/pressbooks/pressbooks-build-tools","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pressbooks%2Fpressbooks-build-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pressbooks%2Fpressbooks-build-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pressbooks%2Fpressbooks-build-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pressbooks%2Fpressbooks-build-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pressbooks","download_url":"https://codeload.github.com/pressbooks/pressbooks-build-tools/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pressbooks%2Fpressbooks-build-tools/sbom","scorecard":{"id":744641,"data":{"date":"2025-08-11","repo":{"name":"github.com/pressbooks/pressbooks-build-tools","commit":"5060240b5685ce7227fd664e48d2a03759c22088"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.8,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Warn: no topLevel permission defined: .github/workflows/release-please.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":10,"reason":"all changesets reviewed","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/pressbooks/pressbooks-build-tools/ci.yml/dev?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/pressbooks/pressbooks-build-tools/ci.yml/dev?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/pressbooks/pressbooks-build-tools/ci.yml/dev?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-please.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/pressbooks/pressbooks-build-tools/release-please.yml/dev?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/ci.yml:29","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   1 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: LICENSE.md:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Branch-Protection","score":5,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'dev'","Info: 'force pushes' disabled on branch 'dev'","Warn: 'branch protection settings apply to administrators' is disabled on branch 'dev'","Warn: 'stale review dismissal' is disabled on branch 'dev'","Warn: required approving review count is 1 on branch 'dev'","Warn: codeowners review is not required on branch 'dev'","Warn: 'last push approval' is disabled on branch 'dev'","Warn: no status checks found to merge onto branch 'dev'","Info: PRs are required in order to make changes on branch 'dev'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-22T18:22:50.195Z","repository_id":27281680,"created_at":"2025-08-22T18:22:50.195Z","updated_at":"2025-08-22T18:22:50.195Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30106488,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-05T01:39:18.192Z","status":"online","status_checked_at":"2026-03-05T02:00:06.710Z","response_time":93,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["assets","eslint","laravel-mix","npm","prettier","stylelint","webpack"],"created_at":"2024-12-10T04:09:35.958Z","updated_at":"2026-03-05T02:13:21.458Z","avatar_url":"https://github.com/pressbooks.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pressbooks Build Tools\n\n[![npm](https://badgen.net/npm/v/pressbooks-build-tools)](https://www.npmjs.com/package/pressbooks-build-tools) [![GitHub release](https://badgen.net/github/release/pressbooks/pressbooks-build-tools)](https://github.com/pressbooks/pressbooks-build-tools/releases/latest) [![license](https://badgen.net/github/license/pressbooks/pressbooks-build-tools)](https://github.com/pressbooks/pressbooks-build-tools/blob/master/LICENSE)\n\nNPM package which includes all asset linting and build tools for Pressbooks projects.\n\n## Installation\n\n```bash\nnpm i -D pressbooks-build-tools\n```\n\n## Usage\n\n### Quick Start\n\n1. **Install the package:**\n```bash\nnpm i -D pressbooks-build-tools\n```\n\n2. **Create a `vite.config.js` in your project root:**\n```javascript\nimport { defineConfig } from 'vite';\nimport { resolve } from 'path';\n\n// Import the WordPress-optimized Vite config\nimport baseConfig from 'pressbooks-build-tools/vite-wp';\n\nexport default defineConfig({\n  ...baseConfig,\n  build: {\n    ...baseConfig.build,\n    rollupOptions: {\n      input: {\n        main: resolve(__dirname, 'assets/src/scripts/main.js'),\n        styles: resolve(__dirname, 'assets/src/styles/main.scss'),\n      },\n    },\n  },\n});\n```\n\n3. **Add scripts to your `package.json`:**\n```json\n{\n  \"scripts\": {\n    \"build\": \"pressbooks-build-tools build\",\n    \"dev\": \"pressbooks-build-tools dev\",\n    \"preview\": \"pressbooks-build-tools preview\",\n    \"lint\": \"pressbooks-build-tools lint\",\n    \"fix\": \"pressbooks-build-tools fix\",\n    \"test\": \"pressbooks-build-tools test\"\n  },\n  \"eslintConfig\": {\n    \"extends\": \"pressbooks-build-tools/eslint\"\n  },\n  \"stylelint\": {\n    \"extends\": \"pressbooks-build-tools/stylelint\"\n  }\n}\n```\n\n### Available Commands\n\n| Command | Description | Example Usage |\n|---------|-------------|---------------|\n| `build` | Build assets for production | `pressbooks-build-tools build` |\n| `dev` | Start development server with hot reload | `pressbooks-build-tools dev` |\n| `preview` | Preview production build locally | `pressbooks-build-tools preview` |\n| `lint` | Run linting on both JavaScript and SCSS files | `pressbooks-build-tools lint` |\n| `lint:scripts` | Run linting on JavaScript files only | `pressbooks-build-tools lint:scripts` |\n| `lint:styles` | Run linting on CSS/SCSS files only | `pressbooks-build-tools lint:styles` |\n| `fix:scripts` | Auto-fix ESLint issues in JavaScript files | `pressbooks-build-tools fix:scripts` |\n| `fix:styles` | Auto-fix Stylelint issues in CSS/SCSS files | `pressbooks-build-tools fix:styles` |\n| `test` | Run linting and build tasks | `pressbooks-build-tools test` |\n\n### Customizing Lint and Fix Commands\n\nBy default, the commands scan:\n- **Scripts:** `config/*.js`, `assets/src/scripts/**/*.js`\n- **Styles:** `**/*.scss`\n\n#### Separate Script and Style Commands\n\nYou can now lint or fix scripts and styles independently:\n\n```bash\n# Lint only JavaScript files\npressbooks-build-tools lint:scripts\n\n# Lint only CSS/SCSS files\npressbooks-build-tools lint:styles\n\n# Fix only JavaScript files\npressbooks-build-tools fix:scripts\n\n# Fix only CSS/SCSS files\npressbooks-build-tools fix:styles\n```\n\n#### Custom File Patterns\n\nYou can customize which directories to scan:\n\n```bash\n# Lint custom script directories\npressbooks-build-tools lint:scripts \"src/**/*.js\" \"lib/**/*.js\"\n\n# Lint custom style directories  \npressbooks-build-tools lint:styles \"assets/css/**/*.scss\" \"themes/**/*.scss\"\n\n# Fix custom script patterns\npressbooks-build-tools fix:scripts \"src/**/*.js\" \"admin/js/**/*.js\"\n\n# Fix custom style patterns\npressbooks-build-tools fix:styles \"assets/src/styles/**/*.scss\"\n\n# Add additional ESLint/Stylelint options\npressbooks-build-tools lint:scripts \"src/**/*.js\" --max-warnings 0\npressbooks-build-tools fix:styles \"assets/**/*.scss\" --cache\n```\n\n#### Package.json Scripts\n\nYou can create granular scripts for different parts of your project:\n\n```json\n{\n  \"scripts\": {\n    \"lint\": \"pressbooks-build-tools lint\",\n    \"lint:scripts\": \"pressbooks-build-tools lint:scripts\",\n    \"lint:styles\": \"pressbooks-build-tools lint:styles\",\n    \"fix\": \"pressbooks-build-tools fix:scripts\",\n    \"fix:scripts\": \"pressbooks-build-tools fix:scripts\", \n    \"fix:styles\": \"pressbooks-build-tools fix:styles\",\n    \n    \"lint:theme\": \"pressbooks-build-tools lint:scripts 'theme/assets/**/*.js' \u0026\u0026 pressbooks-build-tools lint:styles 'theme/assets/**/*.scss'\",\n    \"lint:admin\": \"pressbooks-build-tools lint:scripts 'admin/js/**/*.js' \u0026\u0026 pressbooks-build-tools lint:styles 'admin/css/**/*.scss'\",\n    \"fix:theme\": \"pressbooks-build-tools fix:scripts 'theme/assets/**/*.js' \u0026\u0026 pressbooks-build-tools fix:styles 'theme/assets/**/*.scss'\"\n  }\n}\n```\n\n#### Configuration Options\n\nThe `createViteConfig` function accepts these options:\n\n- `input` - Entry points for your assets (required)\n- `outDir` - Output directory (default: `'assets/dist'`)\n- `port` - Development server port (default: `3100`)\n- `host` - Development server host (default: `'localhost'`)\n- `proxy` - Development server proxy configuration\n- `copyTargets` - Array of files/directories to copy during build (see below)\n- `plugins` - Additional Vite plugins to include\n- `config` - Additional Vite configuration to merge\n\n#### File Copying with copyTargets\n\nFor copying static files (equivalent to Laravel Mix's `.copy()` and `.copyDirectory()`):\n\n```javascript\nexport default createViteConfig({\n  // ... other options ...\n  copyTargets: [\n    // Copy individual files\n    { \n      src: 'node_modules/some-lib/dist/file.js', \n      dest: 'scripts', \n      rename: 'new-name.js' \n    },\n    // Copy directories\n    { \n      src: 'assets/src/images/*', \n      dest: 'images' \n    },\n    // Copy with glob patterns\n    { \n      src: 'node_modules/@vendor/package/dist/**/*', \n      dest: 'vendor/package' \n    }\n  ]\n})\n```\n\n#### Migrating .scripts() Concatenation\n\nLaravel Mix's `.scripts()` method concatenated multiple files. In Vite, create wrapper files instead:\n\n```javascript\n// assets/src/scripts/vendor/jquery-plugins.js\nimport 'jquery-ui/dist/jquery-ui.min.js';\nimport 'jquery-validation/dist/jquery.validate.min.js';\nimport 'select2/dist/js/select2.min.js';\n\n// Then add to your vite.config.js:\ninput: {\n  'jquery-plugins': resolve(__dirname, 'assets/src/scripts/vendor/jquery-plugins.js')\n}\n```\n\n### Linting Configuration\n\n#### ESLint (JavaScript/TypeScript)\n\nPressbooks Build Tools includes [ESLint](https://eslint.org) with a comprehensive configuration. The ESLint config is provided as a `.cjs` file (CommonJS format) because ESLint requires CommonJS when used in ES modules projects.\n\nAdd to your `package.json`:\n```json\n{\n  \"eslintConfig\": {\n    \"extends\": \"pressbooks-build-tools/eslint\"\n  }\n}\n```\n\nOr create a separate `.eslintrc.cjs` file:\n```javascript\nmodule.exports = {\n  extends: ['pressbooks-build-tools/eslint'],\n  // Add your custom rules here\n  rules: {\n    // Override or add rules as needed\n  }\n}\n```\n\n#### Stylelint (CSS/SCSS)\n\nPressbooks Build Tools includes [Stylelint](http://stylelint.io) for CSS and SCSS linting. The Stylelint config is a regular `.js` file since Stylelint handles both CommonJS and ES modules seamlessly.\n\nAdd to your `package.json`:\n```json\n{\n  \"stylelint\": {\n    \"extends\": \"pressbooks-build-tools/stylelint\"\n  }\n}\n```\n\nOr create a separate `.stylelintrc.js` file:\n```javascript\nmodule.exports = {\n  extends: ['pressbooks-build-tools/stylelint'],\n  rules: {\n    // Add your custom rules here\n  }\n}\n```\n\n## Examples\n\n### Basic Plugin Setup\n\nHere's a complete example for a WordPress plugin:\n\n**Directory structure:**\n```\nmy-plugin/\n├── assets/\n│   ├── src/\n│   │   ├── scripts/\n│   │   │   ├── main.js\n│   │   │   └── admin.js\n│   │   └── styles/\n│   │       ├── main.scss\n│   │       └── admin.scss\n│   └── dist/           # Generated by build\n├── vite.config.js\n└── package.json\n```\n\n**package.json:**\n```json\n{\n  \"name\": \"my-plugin\",\n  \"scripts\": {\n    \"build\": \"pressbooks-build-tools build\",\n    \"dev\": \"pressbooks-build-tools dev\",\n    \"lint\": \"pressbooks-build-tools lint\",\n    \"lint:scripts\": \"pressbooks-build-tools lint:scripts\",\n    \"lint:styles\": \"pressbooks-build-tools lint:styles\",\n    \"fix\": \"pressbooks-build-tools fix:scripts\",\n    \"fix:scripts\": \"pressbooks-build-tools fix:scripts\",\n    \"fix:styles\": \"pressbooks-build-tools fix:styles\",\n    \"test\": \"pressbooks-build-tools test\"\n  },\n  \"devDependencies\": {\n    \"pressbooks-build-tools\": \"^5.0.0\"\n  },\n  \"eslintConfig\": {\n    \"extends\": \"pressbooks-build-tools/eslint\"\n  },\n  \"stylelint\": {\n    \"extends\": \"pressbooks-build-tools/stylelint\"\n  }\n}\n```\n\n**vite.config.js:**\n```javascript\nimport { defineConfig } from 'vite';\nimport { resolve } from 'path';\nimport baseConfig from 'pressbooks-build-tools/vite-wp';\n\nexport default defineConfig({\n  ...baseConfig,\n  build: {\n    ...baseConfig.build,\n    rollupOptions: {\n      input: {\n        'my-plugin': resolve(__dirname, 'assets/src/scripts/main.js'),\n        'my-plugin-admin': resolve(__dirname, 'assets/src/scripts/admin.js'),\n        'my-plugin-styles': resolve(__dirname, 'assets/src/styles/main.scss'),\n        'my-plugin-admin-styles': resolve(__dirname, 'assets/src/styles/admin.scss'),\n      },\n    },\n  },\n});\n```\n\n### Theme Setup\n\n**vite.config.js for a theme:**\n```javascript\nimport { defineConfig } from 'vite';\nimport { resolve } from 'path';\nimport baseConfig from 'pressbooks-build-tools/vite-wp';\n\nexport default defineConfig({\n  ...baseConfig,\n  build: {\n    ...baseConfig.build,\n    rollupOptions: {\n      input: {\n        'theme': resolve(__dirname, 'assets/src/scripts/theme.js'),\n        'theme-styles': resolve(__dirname, 'assets/src/styles/style.scss'),\n        'editor-styles': resolve(__dirname, 'assets/src/styles/editor.scss'),\n      },\n    },\n  },\n  server: {\n    ...baseConfig.server,\n    port: 3200, // Custom port for this theme\n  },\n});\n```\n\n**Custom lint patterns for theme:**\n```json\n{\n  \"scripts\": {\n    \"lint:theme-scripts\": \"pressbooks-build-tools lint:scripts 'assets/src/**/*.js'\",\n    \"lint:theme-styles\": \"pressbooks-build-tools lint:styles 'assets/src/**/*.scss'\",\n    \"lint:theme\": \"npm run lint:theme-scripts \u0026\u0026 npm run lint:theme-styles\",\n    \"fix:theme\": \"pressbooks-build-tools fix:scripts 'assets/src/**/*.js' \u0026\u0026 pressbooks-build-tools fix:styles 'assets/src/**/*.scss'\"\n  }\n}\n```\n\n### Advanced Configuration\n\n**vite.config.js with custom plugins and copying:**\n```javascript\nimport { defineConfig } from 'vite';\nimport { resolve } from 'path';\nimport baseConfig from 'pressbooks-build-tools/vite-wp';\nimport { viteStaticCopy } from 'vite-plugin-static-copy';\n\nexport default defineConfig({\n  ...baseConfig,\n  plugins: [\n    ...baseConfig.plugins,\n    viteStaticCopy({\n      targets: [\n        {\n          src: 'node_modules/some-lib/dist/*',\n          dest: 'vendor/some-lib'\n        },\n        {\n          src: 'assets/src/images/*',\n          dest: 'images'\n        }\n      ]\n    })\n  ],\n  build: {\n    ...baseConfig.build,\n    rollupOptions: {\n      input: {\n        'app': resolve(__dirname, 'assets/src/scripts/app.js'),\n        'vendor': resolve(__dirname, 'assets/src/scripts/vendor.js'),\n        'app-styles': resolve(__dirname, 'assets/src/styles/app.scss'),\n      },\n    },\n  },\n  server: {\n    ...baseConfig.server,\n    port: 3300,\n    proxy: {\n      '/wp-admin': {\n        target: 'https://my-local-site.test',\n        changeOrigin: true,\n        secure: false\n      }\n    }\n  },\n});\n```\n\n## Migration from Laravel Mix\n\nIf you're upgrading from a previous version that used Laravel Mix:\n\n1. **Remove old files**: Delete `webpack.mix.js` from your project\n2. **Update package.json**: Replace Mix scripts with Vite scripts (see above)\n3. **Create vite.config.js**: Use the new configuration format\n4. **Update asset paths**: Vite uses different output paths than Mix\n\n### Asset Structure\n\nYour project should have this structure:\n\n```\nyour-plugin/\n├── assets/\n│   ├── src/\n│   │   ├── scripts/\n│   │   │   └── main.js\n│   │   └── styles/\n│   │       └── main.scss\n│   └── dist/           # Generated by build\n├── vite.config.js      # New config file\n└── package.json        # Updated scripts\n```\n\n## Development\n\nThis repo includes test assets to verify that `.js` and `.css/.scss` files compile and linters run. To test your changes:\n\n```\nnpm install\nnpm test\n```\n\nExpected: No errors. Everything is fine.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpressbooks%2Fpressbooks-build-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpressbooks%2Fpressbooks-build-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpressbooks%2Fpressbooks-build-tools/lists"}