Creating a bookmarklet using webpack, bookmarklet-loader, style and css-loader

I am trying to create a bookmarklet using bookmarklet-loader and a style loader and css loader. But I am unable to import css into my bookmarklet.

This is what I have

webpack.config.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
entry: {
    index: './src/index.js',
    bookmarklet: './src/bookmarklets/bookmarklet.js'
},
output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist')
},
target: 'web',
module: {
    rules: [
    {
        test: /\.css$/,
        use: [
            'style-loader',
            'css-loader'
        ]
    },
    {
        test: /\.js$/,
        use: [
           'bookmarklet-loader'
        ],
        include: path.join(__dirname, './src/bookmarklets')
    }
    ]
},
plugins: [
    new CleanWebpackPlugin(['dist']),
    new HtmlWebpackPlugin({
        title: 'Development'
    })
]

Src / bookmarklet / bookmarklet.js:

import './css/style.css';

/* the rest of my bookmarklet code */

Src / index.js:

import bookmarklet from './bookmarklets/bookmarklet';

var add = document.createElement("a");
add.href = "javascript:" + bookmarklet;
add.innerHTML = "Click me";

document.body.appendChild(add);

It just adds a bookmarklet to the link on a blank page, so I can add the link to my browser.

But the launch webpackcauses this error:

SyntaxError: Unexpected token: string (./css/style.css) at [snipped] node_modules/uglify-js/tools/node.js

I tried adding the following to my webpack.config.js:

{
    test: /\.js$/,
    use: [
       'bookmarklet-loader',
       'style-loader',
       'css-loader'
    ],
    include: path.join(__dirname, './src/bookmarklets')
}

Now this compiles fine, but the bookmarklet code contains require statements, so when I try to run it in a browser, I get

Uncaught ReferenceError: require is not defined

I found this and this , but couldn't get it to work.

Edit: . , bookmarklet-loader . -, , css , . webpack, javascript, , .

.json , -:

<snip>
"scripts": {
        "build": "webpack && bookmarklet dist/index.js dist/bookmarklet.js && cat dist/bookmarklet.js | xclip -selection clipboard",
}

npm run build , .

+4
3

, webpack , github "bookmarklet-loader - webpack, javascript , ." , .

,

'use strict';

var uglify = require('uglify-js');

module.exports = function(source) {
  return 'module.exports = "javascript:' + encodeURIComponent(
    '(function(){'+ uglify.minify(source, { fromString: true }).code +'})();'
  ) + '"';
};

, , Uglifyjs, javascript css . , JS, CSS HTML.

, webpack css JS, uri javascript, , URI. DIY webpack. , !

+3

, , webpack .

, <script> webpack:

function addScript(codeURL) {
    const scriptElement = document.createElement('script');
    scriptElement.setAttribute('src', codeURL);
    scriptElement.setAttribute('crossorigin', "anonymous");
    document.body.appendChild(scriptElement);
}

"" index.js :

const add = document.createElement("a");
add.href = "javascript:(function(){s=document.createElement('script');s.type='text/javascript';s.src='bookmarklet.bundle.js';document.body.appendChild(s);})()";
add.innerHTML = "Click me";

, bookmarklet.bundle.js. ( , -)

bookmarklet.js( ):

import './css/style.css';

let elements = require('./someOtherSource');

let list = document.createElement('ul');
for (let i = 0; i < elements.length; ++i) {
    let item = document.createElement('li');
    item.appendChild(document.createTextNode(elements[i]));
    list.appendChild(item);
}
document.body.appendChild(list);

someOtherSource.js , :

module.exports = [ 'a', 'b', 'c'];

, , webpack.config.js :

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
    entry: {
        index: path.resolve(__dirname, 'src/index.js'),
        bookmarklet: path.resolve(__dirname, 'src/bookmarklets/bookmarklet.js'),
    },
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    target: 'web',
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader',
                ]
            },
            {
                test: /\.js$/,
                use: [
                    'babel-loader',
                ],
                exclude: /node_modules/,
            }
        ]
    },
    plugins: [
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
            title: 'Bookmarklet',
            chunks: [ "index" ],
        })
    ]
};

, , , , -, css/less . . .

+5

, , .

bookmarklet, .

(, <link> <script>) , , , , .

, . :

  • JS- CSS + CSS
  • , .

1. Bundle JS CSS

webpack! , , , style-loader, .

, , (, - ..), CSS, , url-loader limit: 0, .

, , (, bookmarklet-loader), , , ( , require).

webpack - , : JavaScript-, .

2.

, URI < <27 > .

, bookmarklet. , , , - JavaScript, " " , :

'javascript:' + encodeURIComponent('(function(){' + code + '})()')

bookmarklet node script ( , , -).

, webpack "bookmarkletify":

function AssetToBookmarkletPlugin() {}

AssetToBookmarkletPlugin.prototype.apply = function (compiler) {
  compiler.plugin('emit', function (compilation, callback) {
    var asset;

    // Rework each asset.
    for (var assetName in compilation.assets) {
      asset = compilation.assets[assetName];
      compilation.assets[assetName] = {
        source: function () {
          // Encode and wrap the original source to make it bookmark-ready.
          return 'javascript:' + encodeURIComponent('(function(){' + asset.source() + '})()');
        },
        size: asset.size
      }
    }

    callback();
  });
};

( , CSS JS, bookmarkletify), - :

const webpack = require('webpack');
const path = require('path');

module.exports = {
  entry: {
    index: './src/index.js'
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist')
  },
  target: 'web',
  module: {
    rules: [{
      test: /\.(png|jpg|gif)$/,
      use: [{
        loader: 'url-loader',
        options: {limit: 0} // 0 = always inline resource
      }]
    }, {
      test: /\.css$/,
      use: ['style-loader', {
        loader: 'css-loader',
        options: {minimize: true} // Minify CSS as well
      }]
    }]
  },
  plugins: [
    new webpack.optimize.UglifyJsPlugin(),
    new AssetToBookmarkletPlugin()
  ]
};

dist/index.js .

+2

Source: https://habr.com/ru/post/1687511/


All Articles